一、 定义
提供一种方法顺序访问一容器对象中的各个元素,而又不需要暴露该对象内部的表示。
二、 角色
- 抽象迭代器(Iterator):定义遍历元素所需方法。
- 具体迭代器(ConcreteIterator):实现具体的遍历方法
- 抽象容器(Aggregate):提供iterator()方法的抽象父类或者接口。
- 具体容器类(ConcreteAggregate):具体容器实现类,实现iterator()方法
相关类图:
三、 需求
创建一种新的容器,实现迭代器,获取所有元素,并打印出来。
四、 代码实现
为了代码简单,在具体容器类中维护了一个list,代替复杂操作,只需要看迭代器的原理就好~
4.1 抽象迭代器
/**
* 抽象迭代器
*
* Created by rytong on 2017/11/13.
*/
public interface Iterator<T> {
/**
* 是否有下一个元素
*
* @return
*/
public boolean hasNext();
public T next();
}
4.2 具体迭代器实现
/**
* 具体的迭代器,迭代器持有容器数据的引用
*
* Created by rytong on 2017/11/13.
*/
public class ConcreteIterator<T> implements Iterator<T> {
/**
* 从容器类传递过来的所有数据
*/
private List<T> list = new ArrayList<T>();
private int cursor = 0;
public ConcreteIterator(List<T> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return cursor != list.size();
}
@Override
public T next() {
return list.get(cursor++);
}
}
4.3 抽象容器接口
/**
* 抽象容器类,提供获取迭代器的方法
*
* Created by rytong on 2017/11/13.
*/
public interface Aggregate {
public Iterator iterator();
}
4.4 具体容器的实现
/**
* 具体容器类
* Created by rytong on 2017/11/13.
*/
public class ConcreteAggregate<T> implements Aggregate {
public List<T> list = new ArrayList<T>();
public void add(T s){
list.add(s);
}
@Override
public Iterator iterator() {
return new ConcreteIterator(list);
}
}
4.5 客户端调用
ConcreteAggregate<String> concreteAggregate = new ConcreteAggregate<String>();
concreteAggregate.add("1");
concreteAggregate.add("3");
concreteAggregate.add("7");
concreteAggregate.add("10");
Iterator<String> iterator = concreteAggregate.iterator();
while(iterator.hasNext()){
String next = iterator.next();
Log.e(TAG,next);
}
运行结果:
11-13 16:05:40.187 9707-9707/com.iteratorpattern E/MainActivity: 1
11-13 16:05:40.187 9707-9707/com.iteratorpattern E/MainActivity: 3
11-13 16:05:40.187 9707-9707/com.iteratorpattern E/MainActivity: 7
11-13 16:05:40.187 9707-9707/com.iteratorpattern E/MainActivity: 10
五、 总结
5.1 优点
- 简化了遍历方式,对于集合的遍历还是比较麻烦的,如果是数组和有序列表,我们还可以使用游标来取得。但用户需要在对集合很了解的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了,引入迭代器后,用户操作就方便多了。
- 可以提供多种遍历方式,比如说对有序列表,可以提供正序遍历和倒序遍历,用户只需要获取两种迭代器获取相应的数据即可。
5.2 缺点
- 对于比较简单的遍历,使用迭代器比较复杂,比起迭代器,开发人员更愿意使用for循环和get方法根据角标来取值。
5.3 适用场景
迭代器模式和集合是共生死的,一般来说,实现了一个集合就得提供这个集合的迭代器,就像java中的Collection,List,Set,Map等,这些集合都有自己的迭代器。假如我们也要实现一个这样的容器,那么也需要引入迭代器。