java.util.Iterator接口描述的是以统一的方式对各种集合元素进行遍历/迭代的工具,也称“迭代器”。

迭代器(Iterator)模式,又叫做游标(Cursor)模式,是用于遍历集合类的标准访问方法。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。

java.util.Iterator接口的定义:

     public interface Iterator {          

boolean hasNext();           //是否有下一个,有返回true,否则返回false

Object next();                //遍历到下一个

void remove();               //删除当前元素

}

不难看出,允许在“遍历”过程中移除集合中的(当前遍历到的那个)元素。

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

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

Object o = it.next();           // o的操作...      

}

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


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

     for(int i=0; i<array.size(); i++) { ... get(i) ... }

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

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

以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。而且,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。



例如1TestIterator.java

import java.util.Date;

import java.util.ArrayList;

import java.util.Vector;

import java.util.Iterator;


public class TestIterator{

      public static void main(String[] args) {

             ArrayList a = new ArrayList();

             a.add("China");

             a.add("USA");

             a.add("Korea");

             Iterator  it = a.iterator();             //it完成遍历

             while(it.hasNext()){

                    String country = (String)it.next();  //这样就返回String类型

                    System.out.println(country);

             }          


             Vector v = new Vector();

             v.addElement(new Date());  

             v.addElement(new Date(200008755554L));

             it = v.iterator();

             while(it.hasNext()){

                    Date time = (Date)it.next();

                    System.out.println(time);    

             }                  

      }

}

输出结果:

China

USA

Korea

Sun Dec 27 18:53:27 CST 2009

Tue May 04 05:59:15 CST 1976


例如2Person.javaTestIterator2.java

注:本例有两个文件,如果放在同一个包里可以直接使用;如果在不同包,需用import一下。

(1) Person.java

package test.src.test;  //这是我的Person.java文件所在包,需根据实际情况修改

public class Person{

      private String name;

      private int age;


      public Person(String name,int age){

             this.name = name;

             this.age = age;

      }

      public void setName(String name){

             this.name = name;

      }

      public String getName(){

             return name;  

      }

      public void setAge(int age){

             this.age = age;

      }

      public int getAge(){

             return age;    

      }

      public String toString(){

             return "Name: " + name + "/tAge: " + age;

      }    

}

(2) TestIterator2.java

package test.src.test;          //同理,需根据实际情况修改

import java.util.Vector;

import java.util.Iterator;

public class TestIterator2{

      public static void main(String[] args) {

             Vector v = new Vector();

             v.addElement(new Person("张三",18));

             v.addElement(new Person("李四",26));

             v.addElement(new Person("王五",34));

             v.addElement(new Person("赵六",40));


             Iterator it = v.iterator();

             while(it.hasNext()){  //while循环输出每一个元素

                    Person p = (Person)it.next();

                    System.out.println(p);  

                    if(p.getName().equals("王五")){

                           p.setAge(p.getAge() + 50);

                    }else if(p.getName().equals("李四")){

                           it.remove();

                    }                  

             }    

             System.out.println("-----------------------");

             for(int i=0;i<v.size();i++)

                    System.out.println(v.elementAt(i));    

      }

}


输出结果:

Name: 张三  Age: 18

Name: 李四  Age: 26

Name: 王五  Age: 34

Name: 赵六  Age: 40

-----------------------

Name: 张三  Age: 18

Name: 王五  Age: 84

Name: 赵六  Age: 40