顺序访问聚集中的对象,主要用于集合中。一是需要遍历的对象,即聚集对象,二是迭代器对象,用于对聚集对象进行遍历访问。 迭代子模式为遍历集合提供了统一的接口方法。从而使得客户端不需要知道聚集的内部结构就能就能对聚集进行遍历等操作。Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。
例如,如果没有使用Iterator,遍历一个数组的方法是使用索引:
for(int i=0; i<array.size(); i++) {
… get(i) … }
而访问一个链表(LinkedList)又必须使用while循环:
while((e=e.next())!=null) { … e.data() … }
以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。
更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
为解决以上问题,Iterator模式总是用同一种逻辑来遍历集合:
for(Iterator it = c.iterater();
it.hasNext(); ) { … }
奥秘在于客户端自身不维护遍历集合的”指针”,所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。
客户端从不直接和集合类打交道,它总是控制Iterator,向它发送”向前”,”向后”,”取当前元素”的命令,就可以间接遍历整个集合。
好的,迭代子模式主要有5个对象
抽象迭代子角色:定义了遍历聚集的接口。
具体迭代子角色:实现了抽象迭代子接口。
抽象聚集角色:定义聚集的公共方法,并为聚集创建迭代子(Iterator)对象。
具体聚集角色:能够返回一个实现迭代子(Iterator)接口的迭代子实例。
客户端角色:持有对聚集和迭代子实例的引用,通过迭代子对聚集进行迭代。
抽象迭代子角色:
package iterator; public interface Iterator { public Object First(); public Object previous(); public Object Next(); public boolean hasNext(); }
抽象聚集角色:
package iterator; public abstract class Collection { public abstract Iterator iterator(); public abstract int size(); public abstract Object getElement(int index); }
具体聚集角色:
package iterator; public class ChildCollection extends Collection{ //创建一个字符串数组 public String items[] = {"A","B","C","D","E"}; /*集合初始化,获取集合实例*/ @Override public Iterator iterator() { return new IteratorImplement(this); } /*获取数组的长度*/ @Override public int size() { return items.length; } /*获取数组元素的位置*/ @Override public Object getElement(int index) { return items[index]; } }
具体迭代子角色:
package iterator; public class ChildCollection extends Collection{ //创建一个字符串数组 public String items[] = {"A","B","C","D","E"}; /*集合初始化,获取集合实例*/ @Override public Iterator iterator() { return new IteratorImplement(this); } /*获取数组的长度*/ @Override public int size() { return items.length; } /*获取数组元素的位置*/ @Override public Object getElement(int index) { return items[index]; } }
客户端角色:
package iterator; public class Client { public static void main(String[] args) { /*创建实例*/ Collection collection=new ChildCollection(); /*获取集合迭代对象*/ Iterator iterator=collection.iterator(); while(iterator.hasNext()){ System.out.println(iterator.Next()); } } }
结果:
A B C D E
可以看看jdk源码,我们实现了jdk中Iterator的功能。有点区别就是Collection也实现了Iterator接口,在Collection子类里面可以根据不同的类(比如数组、ArrayList、LinkedList)在各个类实现Iterator接口,仅仅是内部实现的方式不一样,实现方法是一样的。