介绍:
迭代器模式属于行为型模式。它提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
类图:
Iterator(迭代器接口):定义、访问和遍历元素的接口
ConcreteIterator(具体迭代器类):实现迭代器接口,并记录遍历的当前位置
Aggregate(容器接口):提供创建具体迭代器角色的接口
ConcreteAggregate(具体容器类):实现容器接口功能
用法:
• 遍历一个集合对象的时候
个人理解:
这个模式比较古老,很多语言也会自带这种模式,比如Java中的List、Map、数组等也已经封装了这种方法了。实际开发中我们已经不会再使用这个模式了。for循环、foreach循环已经很满足我们的开发需求了。
例子:
这种模式的学习价值还是很高的,我们就过一遍如何使用这个模式。
需求:实现迭代器
1、定义Iterator接口
public interface Iterator<T> {
//是否有下一个元素
boolean hasNext();
//返回当前位置元素并将位置移到下一位
T next();
}
此接口用于统一业务层的抽象方法。帮助集合对象遍历的时候不暴露该对象的内部表示。
2、实现ConcreteIterator类
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> list = new ArrayList<>();
private int cursor = 0;
public ConcreteIterator(List<T> list){
this.list = list;
}
@Override
public boolean hasNext() {
return cursor != list.size();
}
@Override
public T next() {
T obj = null;
if (this.hasNext()){
obj = this.list.get(cursor++);
}
return obj;
}
}
为了方便操作,我们集合对象的数组用List表示,原则上是用Object[]。在Iterator接口中的方法,遍历时业务层只关注:有没有后面一个hasNext()、获得的元素是什么next(),而具体实现的细节就是Iterator做好了。
3、定义Aggregate接口
public interface Aggregate<T> {
void add(T obj);
void remove(T obj);
Iterator<T> iterator();
}
此接口创建迭代器,并为集合中的元素对象提供操作方法。
4、实现ConcreteAggregate类
public class ConcreteAggregate<T> implements Aggregate<T>{
private List<T> list = new ArrayList<>();
@Override
public void add(T obj) {
list.add(obj);
}
@Override
public void remove(T obj) {
list.remove(obj);
}
@Override
public Iterator<T> iterator() {
return new ConcreteIterator<T>(list);
}
}
Aggregate的核心就是创建一个迭代器,把组装好的数据交给迭代器去遍历。
5、测试与运行结果
public class Test {
public static void main(String[] args) {
Aggregate<String> a = new ConcreteAggregate<>();
a.add("A");
a.add("B");
a.add("C");
a.add("D");
Iterator<String> i = a.iterator();
while (i.hasNext()){
System.out.println(i.next());
}
}
}
运行结果:
A
B
C
总结:
迭代器模式分离了对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部数据。