迭代器模式-提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
Iterator迭代器接口(去掉了源码中的注释):
package java.util;
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}
Iterable接口(可迭代的类接口):
public interface Iterable<T> {
Iterator<T> iterator();
}
ContreteAggregate(聚集类):
package com.hy.messTest;
import java.util.Iterator;
public class ConcreteAggregate<E> implements Iterable<E> {
private static final int INCREMENT = 10;
@SuppressWarnings("unchecked")
private E[] array = (E[]) new Object[10];
private int size;
public void add(E e) {
if (size < array.length) {
array[size++] = e;
} else {
@SuppressWarnings("unchecked")
E[] copy = (E[]) new Object[array.length + INCREMENT];
System.arraycopy(array, 0, copy, 0, size);
copy[size++] = e;
array = copy;
}
}
public Object[] toArray() {
Object[] copy = new Object[size];
System.arraycopy(array, 0, copy, 0, size);
return copy;
}
public int size() {
return size;
}
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor = 0;
public boolean hasNext() {
return cursor != size();
}
public E next() {
return array[cursor++];
}
public void remove() {
}
}
}
测试类:
package com.hy.messTest;
import java.util.Iterator;
public class IteratorTest {
public static void main(String[] args) {
ConcreteAggregate<Integer> ca = new ConcreteAggregate<Integer>();
for (int i = 0; i < 10; i++) {
ca.add(i);
}
Iterator<Integer> it = ca.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
}
测试结果是输出从0-9。
以上的具体聚集类,实现了自己的迭代,而且对外部没有暴露对象的内部表示,外界只知道认识Iterator即可。
java中在此基础上有foreach语法,所以上面的遍历部分可以这么写:
for (Integer integer : ca) {
System.out.print(integer + " ");
}
值得注意的是,这里的具体聚集类采用的内部类作为各个集合类迭代器的实现,内部类可以完全杜绝客户端对迭代器实现类的依赖,隐藏了实现细节,并且迭代器的实现类可以自由的使用集合类的各个属性,而不需要集合类提供自己属性访问的接口以及建立二者的关联关系。
不过缺点也接踵而至,由于具体的集合类与具体的迭代器是绑定的关系,所以这种实现方式在复用的过程中会有很大的限制甚至是不能复用。
总结:
迭代器模式是为了在隐藏聚合对象的内部表示的前提下,提供一种遍历聚合对象元素的方法。而且使用内部类将细节包装在集合类内部隐藏起来,使得外部无法访问集合类的任何一个属性。
这当中还使用到了工厂方法模式,这个在工厂方法模式一章中,对于迭代器的产生,是工厂方法模式处理的。两个设计模式互相结合,让JAVA的集合框架更加优美、健壮。
PS:
JVM对于foreach的执行过程,其实相当于下面的代码。
for (Iterator iterator = arrayList.iterator(); iterator.hasNext();) {
Integer i = (Integer) iterator.next();
System.out.println(i);
}