迭代器模式:在不暴露一个聚合对象的内部表示的情况下,提供一种方法来按顺序访问该对象中的各个元素。
抽象出一个聚合类,该类提供一个方法iterator()返回这个聚合类对应的迭代器:
public interface Aggregate<T> {
Iterator<T> iterator();
void add(T t);
void remove(T t);
}
迭代器抽象类,可以抽象出hasNext()和next()方法,供子类去实现不同的迭代方式,并定义一个默认序号:
public abstract class Iterator<T> {
int index = -1;
abstract T first();
abstract T next();
abstract boolean hasNext();
}
具体聚合类,继承父接口重写iterator()返回迭代器,内部保存一个容器,向外提供添加和删除元素的方法:
public class ConcreteAggregate implements Aggregate<String> {
List<String> lists = new ArrayList<>();
@Override
public Iterator<String> iterator() {
return new ForwardIterator(this);
// return new BackwardIterator(this);
}
@Override
public void add(String s) {
lists.add(s);
}
@Override
public void remove(String s) {
lists.remove(s);
}
}
正序迭代器,构造方法传入一个对应的聚合类,重写获取元素的几个方法:
public class ForwardIterator extends Iterator<String> {
private ConcreteAggregate target;
public ForwardIterator(ConcreteAggregate target) {
this.target = target;
}
@Override
public String first() {
return target.lists.get(0);
}
@Override
public String next() {
return target.lists.get(++index);
}
@Override
public boolean hasNext() {
int tempIndex = index + 1;
return tempIndex < target.lists.size();
}
}
使用迭代器去遍历聚合类:
public class Main {
public static void main(String[] args) {
final ConcreteAggregate concreteTarget = new ConcreteAggregate();
for (int i = 0; i < 10; i++) {
concreteTarget.add("Item " + i);
}
final Iterator<String> iterator = concreteTarget.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
倒叙迭代器的实现,迭代器的切换只要在ConcreteAggregate类中iterator()返回不同的迭代器即可。
public class BackwardIterator extends Iterator<String> {
private ConcreteAggregate target;
public BackwardIterator(ConcreteAggregate target) {
this.target = target;
index = this.target.lists.size();
}
@Override
String first() {
final int size = target.lists.size();
return size > 0 ? target.lists.get(size - 1) : null;
}
@Override
String next() {
return target.lists.get(--index);
}
@Override
boolean hasNext() {
final int tempIndex = index - 1;
return tempIndex >= 0;
}
}
迭代器模式的好处在于把遍历行为抽离了出来,屏蔽了内部实现,也提供了良好的扩展性。