迭代器模式的核心是将遍历逻辑从容器中分离,由独立迭代器对象承担,从而解耦容器结构与遍历方式。它包含Iterator、ConcreteIterator、Aggregate、ConcreteAggregate四个角色,通过统一接口实现不同容器的遍历一致性,并需注意状态保持、松耦合及线程安全等细节。

迭代器模式的核心,是把“怎么遍历”从容器本身剥离开,让容器只管存数据,遍历逻辑由独立的迭代器对象承担。这样既不暴露数组、链表或树的内部结构,又能让同一段遍历代码适配不同容器。
为什么需要把遍历逻辑单独抽出来
直接在容器里写 for 循环或 while 遍历,会带来几个实际问题:
- 每换一种数据结构(比如从 ArrayList 改成 LinkedList),遍历代码就得重写
- 客户端必须了解容器底层是用数组还是指针链接,一改结构就容易出错
- 想加个逆序遍历、跳步遍历或过滤遍历,就得在容器类里堆逻辑,违背单一职责
四个关键角色各司其职
一个标准的迭代器模式由四部分组成,缺一不可:
-
Iterator 接口:只定义最基础的操作,比如
hasNext()和next(),有些还加remove()或first() - ConcreteIterator:真正干活的实现类,它知道怎么在具体容器里移动指针、判断边界、取当前元素
-
Aggregate 接口:声明一个方法,比如
createIterator(),告诉外界“我能给你一个遍历我的方式” - ConcreteAggregate:比如 ArrayList 或自定义的 TreeContainer,它实现 Aggregate 接口,并返回对应的 ConcreteIterator 实例
典型使用流程其实很直白
客户端拿到容器后,并不自己操心下标或 next 指针,而是走标准三步:
- 调用容器的
iterator()方法,拿到一个迭代器对象 - 用
hasNext()判断是否还有元素可读 - 用
next()取出当前元素并推进位置
整个过程对 ArrayList、HashSet、甚至你写的二叉树容器,写法完全一样——接口统一,实现隔离。
实际开发中要注意的细节
不是只要写个 hasNext/next 就算完成迭代器。几个关键点常被忽略:
- 迭代器应持有状态:比如当前索引、当前节点引用,不能每次 next 都从头查起
- 避免强耦合:ConcreteIterator 和 ConcreteAggregate 虽然要配合工作,但通过接口通信,不能互相 import 具体类
- 线程安全需额外考虑:标准 Iterator 不保证并发安全,如需多线程遍历,得加锁或用 CopyOnWriteArrayList 这类自带安全机制的容器
- Java 中的 fail-fast 机制就是靠迭代器记录容器修改次数(modCount)来实现的,一旦发现不一致立刻抛 ConcurrentModificationException










