-
迭代器设计模式(Iterator Pattern)
- 提供一种方法顺序访问一个聚合对象中各个元素,而又无需暴露该对象的内部实现,属于行为型模式
- 应该是Java中应用最多的设计模式之一
- 提到迭代器,想到它是与集合相关的,集合也叫容器,可以将集合看成是一个可以包容对象的容器,例如List、Set、Map,甚至数组都可以叫做集合,迭代器的作用就是把容器中的对象一个一个地遍历出来
-
应用场景
- 一般来说,迭代器模式是与集合共存的,只要实现一个集合,就需要同时提供这个集合的迭代器,就像Java中的Collection,List、Set、Map等都有自己的迭代器
- Java中的Iterator迭代器
-
角色
-
抽象容器(Aggregate):提供创建具体迭代器角色的接口,一般是接口,包括一个iterator()方法,例如Java中的Collection接口,List接口、Set接口等
-
具体容器角色(ConcreteAggregate):实现抽象容器的具体实现类,例如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet等
-
抽象迭代器角色(Iterator):负责定义访问和遍历元素的接口,包括几个核心方法,取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移除当前对象的方法remove()
-
具体迭代器角色(ConcreteIterator):实现迭代器接口中定义的方法,并要记录遍历中的当前位置,完成集合的迭代
-
-
代码示例,自定义集合容器简化版
import java.util.ArrayList; import java.util.List; /** * 抽象迭代器 */ interface Iterator { /** * 是否有下一个元素 * * @return */ boolean hasNext(); /** * 获取下个元素 * * @return */ Object next(); /** * 删除元素 * * @param obj * @return */ Object remove(Object obj); } /** * 具体的迭代器 */ class ConcreteIterator implements Iterator { private List list; private int index = 0; public ConcreteIterator(List list) { this.list = list; } @Override public boolean hasNext() { if (index == list.size()) { return false; } return true; } @Override public Object next() { Object obj = null; if (this.hasNext()) { obj = this.list.get(index); index++; } return obj; } @Override public Object remove(Object obj) { return this.list.remove(obj); } } /** * 抽象容器 */ interface ICollection { void add(Object obj); void remove(Object obj); Iterator iterator(); } /** * 具体容器 */ class MyCollection implements ICollection { private List list = new ArrayList(); @Override public void add(Object obj) { list.add(obj); } @Override public void remove(Object obj) { list.remove(obj); } @Override public Iterator iterator() { return new ConcreteIterator(list); } } public class Main { public static void main(String[] args) { MyCollection collection = new MyCollection(); collection.add("哈哈哈"); collection.add("嘿嘿嘿"); collection.add("嘻嘻嘻"); Iterator iterator = collection.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println(obj); } } }
-
优点
- 可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合内部的数据
- 支持以不同的方式遍历一个聚合对象
-
缺点
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐
- 迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常