迭代器模式(Iterator Pattern):统一访问集合元素的方式
迭代器模式是行为型设计模式的一种,核心思想是提供一种统一的方法顺序访问容器对象(如集合、数组)中的各个元素,而不暴露容器的内部结构。这种模式就像 “遥控器”—— 无论电视机的内部构造如何,用户只需通过遥控器的按键(迭代器方法)就能逐频道切换(遍历元素),无需了解电视的内部细节。
迭代器模式的核心结构
迭代器模式通过四个核心角色实现对容器元素的统一遍历,职责明确且解耦了容器与遍历逻辑:
迭代器接口(Iterator)
- 定义遍历容器元素的标准接口,通常包含以下方法:
hasNext():判断是否还有下一个元素。next():返回当前元素,并移动到下一个位置。- (可选)
remove():移除当前元素(视容器支持情况)。
- 示例:
java.util.Iterator(Java 集合框架的迭代器接口)。
具体迭代器(ConcreteIterator)
- 实现迭代器接口,封装具体的遍历逻辑,记录当前遍历位置,与特定容器绑定。
- 示例:
ArrayList的内部迭代器(遍历数组)、LinkedList的内部迭代器(遍历链表)。
容器接口(Collection/Aggregate)
- 定义容器的核心接口,声明创建迭代器的方法(
iterator()),是所有容器的抽象父类。 - 示例:
java.util.Collection(Java 集合的根接口)。
具体容器(ConcreteCollection)
- 实现容器接口,存储元素并提供创建对应迭代器的方法,负责管理元素的增删改查。
- 示例:
ArrayList(数组容器)、HashSet(哈希表容器)。
代码实现示例
以 “自定义列表容器” 为例,展示迭代器模式的实现:自定义MyList容器,通过迭代器遍历元素,不暴露内部存储结构(如数组)。
1. 迭代器接口与具体迭代器
1 | // 1. 迭代器接口 |
2. 容器接口与具体容器
1 | // 3. 容器接口 |
3. 客户端使用
1 | public class IteratorDemo { |
输出结果
1 | 元素1 |
迭代器模式的核心优势
- 统一遍历接口
无论容器内部结构是数组、链表还是哈希表,客户端都可通过相同的hasNext()和next()方法遍历,无需关心容器的具体实现(如ArrayList和LinkedList的遍历代码完全一致)。 - 隐藏容器内部结构
客户端仅通过迭代器访问元素,无需知道容器是用数组还是链表存储的,降低了客户端与容器的耦合度,保护了容器的封装性。 - 支持多种遍历方式
一个容器可提供多个迭代器实现不同的遍历逻辑(如正向遍历、反向遍历、过滤遍历),客户端可根据需求选择。 - 简化容器接口
容器无需暴露大量遍历相关的方法(如get(int index)可能仅用于内部),只需提供iterator()方法即可。
适用场景
- 需要统一遍历不同容器
当系统中存在多种容器(如数组、集合、树),且希望用相同的代码遍历它们时(如 Java 集合框架的for-each循环)。 - 不希望暴露容器内部结构
容器的内部实现(如哈希表的桶数组、链表的节点)属于私有细节,不应暴露给客户端,迭代器是安全的访问方式。 - 需要多种遍历方式
如对列表需要正向遍历、反向遍历或按条件筛选遍历,可通过不同的迭代器实现。 - 迭代逻辑复杂或易变
将遍历逻辑封装在迭代器中,便于修改或扩展(如优化遍历性能),不影响容器本身。
优缺点分析
优点
- 遍历接口统一:客户端代码更简洁,无需针对不同容器编写不同遍历逻辑。
- 封装性好:容器内部结构对客户端透明,降低耦合度。
- 扩展性强:新增容器或迭代方式时,只需实现对应的容器和迭代器接口,不影响现有代码。
缺点
- 额外的类开销:每个容器需对应一个或多个迭代器类,增加了系统的类数量。
- 迭代器与容器绑定:迭代器依赖于特定容器,更换容器可能需要更换迭代器(但客户端无需修改遍历代码)。
经典应用:Java 集合框架的迭代器
Java 的java.util.Iterator是迭代器模式的典范,几乎所有集合类(ArrayList、HashMap、TreeSet等)都实现了Iterator接口,使遍历代码高度统一:
1 | // 遍历ArrayList |
甚至可通过增强 for 循环(for-each)简化遍历,其底层仍依赖迭代器:
1 | for (String s : arrayList) { |
总结
迭代器模式通过分离容器与遍历逻辑,提供了一种统一、安全的元素访问方式,是处理集合类数据的核心模式。其核心价值在于 “接口统一” 和 “封装内部结构”,使客户端能专注于元素的使用而非容器的实现

v1.3.10