Java学习之Iterator(迭代器)的一般用法

来源:互联网 发布:redis重启后数据丢失 编辑:程序博客网 时间:2024/06/18 14:41

迭代器(Iterator

 

  迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

 

  Java中的Iterator功能比较简单,并且只能单向移动:

 

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iteratornext()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,Collection继承。

 

  (2) 使用next()获得序列中的下一个元素。

 

  (3) 使用hasNext()检查序列中是否还有元素。

 

  (4) 使用remove()将迭代器新返回的元素删除。

 

  IteratorJava迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

 

迭代器应用:

 list new ArrayList();

 l.add("aa");

 l.add("bb");

 l.add("cc");

 for (Iterator iter l.iterator(); iter.hasNext();) {

  String str (String)iter.next();

  System.out.println(str);

 }

//迭代器用于while循环

 Iterator iter l.iterator();

 while(iter.hasNext()){

  String str (String) iter.next();

  System.out.println(str);

 }


 用Iterator模式实现遍历集合

Iterator模式 是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。

例如,如果没有使用Iterator,遍历一个数组的方法是使用索引:

for(int i=0;i

而访问一个链表(LinkedList)又必须使用while循环:

while((e=e.next())!=null){...e.data()...}

    以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。

    更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。

    为解决以上问题,Iterator模式总是用同一种逻辑来遍历集合:

for(Iterator it=c.iterater();it.hasNext();){ ...}

    奥秘在于客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。

    客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。

 

首先看看java.util.Iterator接口的定义:

public interface Iterator {

  boolean hasNext();

  Object next();

  void remove();

}

    依赖前两个方法就能完成遍历,典型的代码如下:

for(Iterator it=c.iterator();it.hasNext();){

  Object o=it.next();

  // 对o的操作...

}

    在JDK1.5中,还对上面的代码在语法上作了简化:

// Type是具体的类型,如String。

for(Type t:c){

// 对t的操作...

}

    每一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree 可能返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心到底是哪种Iterator,它只需要获得这个 Iterator接口即可,这就是面向对象的威力。

    要确保遍历过程顺利完成,必须保证遍历过程中不更改集合的内容(Iterator的remove()方法除外),因此,确保遍历可靠的原则是只在一个线程中使用这个集合,或者在多线程中对遍历代码进行同步。

Iterator示例:

Collection c=new ArrayList();

c.add("abc");

c.add("xyz");

for(Iterator it=c.iterator();it.hasNext();){

String s=(String)it.next();

System.out.println(s);

}

    如果你把第一行代码的ArrayList换成LinkedList或Vector,剩下的代码不用改动一行就能编译,而且功能不变,这就是针对抽象编程的原则:对具体类的依赖性最小。

0 0
原创粉丝点击