Iterator是典型行为型设计模式,通过分离遍历逻辑与数据结构,以hasNext()和next()统一接口解耦容器实现,避免客户端暴露内部细节、重复编写遍历代码,并支持fail-fast安全机制及foreach语法糖底层支撑。

Java 中的 Iterator 不是语法糖,而是一个典型的行为型设计模式落地——它把“怎么遍历”从容器中彻底剥离出来,让集合只管存,迭代器只管取。
为什么要把遍历逻辑单独抽出来?
没有迭代器时,遍历方式和数据结构强耦合:
- 数组靠下标
arr[i],链表用node.next,哈希表根本没法按序索引; - 客户端每次换一种集合,就得重写一套循环逻辑;
- 暴露内部结构(比如
ArrayList的elementData数组)会破坏封装,也容易引发误操作。
迭代器模式用统一接口 hasNext() 和 next() 把差异收口,调用方只认这个契约,不关心背后是数组、链表还是跳表。
Iterator 接口背后的角色分工
一个标准实现包含四个关键角色:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
-
Iterator 接口:定义遍历行为,最小契约就是
hasNext()和next(),remove()是可选操作; -
ConcreteIterator(如
ArrayList.Itr):持有游标(cursor)、记录当前访问位置,并与具体容器协作获取元素; -
Aggregate 接口(对应 Java 中的
Collection):声明iterator()方法,把创建迭代器的责任明确下来; -
ConcreteAggregate(如
ArrayList):内部维护数据结构,但只对外返回迭代器,不暴露elementData等字段。
fail-fast 机制是怎么工作的?
这是迭代器保障遍历安全的关键设计:
- 容器(如
ArrayList)维护一个modCount,每次增删改都会自增; - 迭代器创建时拷贝一份
expectedModCount; - 每次调用
next()或hasNext()前,先比对两者是否一致; - 不一致就抛
ConcurrentModificationException,避免遍历时结构被意外修改导致数据错乱或无限循环。
注意:这个机制只针对单线程下的“快速失败”,不是线程安全保证。多线程场景需用 CopyOnWriteArrayList 或同步控制。
foreach 语法糖到底做了什么?
写 for (String s : list) 时,编译器自动翻译为:
while (it.hasNext()) {
String s = it.next();
// 原来的循环体
}
也就是说,foreach 的底层完全依赖 iterator() 方法返回的对象。只要类实现了 Iterable 接口(即提供 iterator()),就能用 foreach 遍历——这也是自定义容器支持该语法的唯一要求。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










