一、模式介绍
迭代器模式为我们提供一种按照顺序访问集合容器中对象元素的方法,而无需暴露集合内部细节表示。无论是什么类型的容器,迭代器模式都能为其提供一致的遍历行为,不用关心容器内部元素的组成结构。
通常迭代器模式会包含如下四种角色:
- 抽象迭代器,定义访问和遍历元素的行为;
- 具体迭代器,实现具体的遍历元素的行为逻辑;
- 抽象容器,定义元素的增删行为,还有获取迭代器的行为;
- 具体容器,实现容器的具体增删行为,和获取迭代器的具体逻辑;
通用实现代码如下:
public interface Iterator<E> {
E next();
boolean hasNext();
}
public class ConcreteIterator<E> implements Iterator {
private List<E> list;
private int cursor = 0;
public ConcreteIterator(List<E> list){
this.list = list;
}
@Override
public Object next() {
return list.get(cursor++);
}
@Override
public boolean hasNext() {
return cursor < list.size();
}
}
public interface Container<E> {
boolean add(E element);
boolean remove(E element);
Iterator<E> iterator();
}
public class ConcreteContainer<E> implements Container<E>{
private List<E> list = new ArrayList<>();
@Override
public boolean add(E element) {
return list.add(element);
}
@Override
public boolean remove(E element) {
return list.remove(element);
}
@Override
public Iterator<E> iterator() {
return new ConcreteIterator<E>(list);
}
}
@Slf4j
public class Main {
public static void main(String[] args) {
Container<String> strContainer = new ConcreteContainer<String>();
strContainer.add("jack");
strContainer.add("tom");
strContainer.add("lily");
Iterator<String> strIterator = strContainer.iterator();
while(strIterator.hasNext()){
log.info("{}", strIterator.next());
}
}
}
可以看到,无论是什么类型的容器,其底层实现还是需要依靠JDK提供的集合框架类,但是我们可以进行封装,使其具有业务特点,同时在其内部实现迭代器的获取方式,如此无论什么类型的容器,我们只要这一个迭代器就够了。
二、使用案例
- JDK中的Iterator和ArrayList;
三、模式总结
3.1 优点
- 为不同的容器提供了一致的遍历行为,符合代码复用原则;
- 将容器和迭代行为进行分离,集合对象无需关心具体的迭代行为;
- 每个容器可以拥有多个迭代器,来实现不同需要的迭代行为;
3.2 缺点
- 日常开发中,使用JDK提供的集合和迭代器即可,一般很少自己实现迭代器模式;