如果我们需要遍历一个集合中的对象,但是又不想暴露该集合中的内部表示的时候,我们可以考虑迭代器模式。迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。我们在遍历过程中把游走的任务放在迭代器上,而不是聚合上,这样简化了聚合的接口和实现,也让责任各得其所。
1.适用性和优缺点
1.适用性
a.访问一个聚合对象的内容而无需暴露它的内部表示。
b.支持对聚合对象的多种遍历。
c.为遍历不同的聚合结构提供一个统一的接口(支持多态迭代)。
2.优点
a.它支持以不同的方式遍历一个聚合对象。
b.迭代器简化了聚合类。
c.在迭代器模式中。增加新的聚合类和迭代器类都很方便,无须修改原有代码。
新的聚合类需要对应增加新的迭代器类,类的数目大大增加,增加系统的复杂性。
2.示例讲解
本文讲一个遍历数组的例子,迭代器模式首先需要定义一个迭代器接口。接着创建一个聚合对象接口,然后实现聚合对象,最后实现一个迭代器,将聚合对象传入迭代器中。
首先建立一个Iterator接口:
package iteratorpattern;
public interface Iterator {
Object next();
void first();
void last();
boolean hasNext();
}
实现接口:
package iteratorpattern;
public class IteratorImpl implements Iterator {
private List list;
private int index;
public IteratorImpl(List list) {
index = 0;
this.list = list;
}
public void first() {
index = 0;
}
public void last() {
index = list.getSize();
}
public Object next() {
Object obj = list.get(index);
index++;
return obj;
}
public boolean hasNext() {
return index < list.getSize();
}
}
然后是定义一个list接口
package iteratorpattern;
public interface List {
Iterator iterator();
Object get(int index);
int getSize();
void add(Object obj);
}
然后实现list接口
package iteratorpattern;
public class ListImpl implements List {
private Object[] list;
private int index;
private int size;
public ListImpl() {
index = 0;
size = 0;
list = new Object[100];
}
public Iterator iterator() {
return new IteratorImpl(this);
}
public Object get(int index) {
return list[index];
}
public int getSize() {
return this.size;
}
public void add(Object obj) {
list[index++] = obj;
size++;
}
}
测试程序:
package iteratorpattern;
public class Test {
public static void main(String[] args) {
List list = new ListImpl();
list.add("a");
list.add("b");
list.add("c");
//第一种迭代方式
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println("=====");
//第二种迭代方式
for (int i = 0; i < list.getSize(); i++) {
System.out.println(list.get(i));
}
}
}
测试结果如下:
a
b
c
=====
a
b
c
根据以上示例我们可以知道,这个模式很熟悉,我们都使用过java.util.*包下的ArrayList吧,这个类自带的Iterator就是用来迭代遍历ArrayList中的元素的。我们也可以发现,list实现类中对于获取迭代器的方法中需要创建相应的迭代器实现类的对象,因此一个迭代器类和一个list类是对应的。因此如果要增加list类,系统的类成倍增加,增加了系统的复杂性。其实,迭代器模式一般不会单独拿出来使用,对于聚合对象的遍历,我们可以直接使用集合相应的Iterator方法即可。