基本概念
迭代器模式:一种行为型设计模式,它提供一种顺序访问集合对象元素的方法,而无需暴露集合的内部表示。通过将遍历逻辑与集合本身解耦,使得不同遍历方式可以独立变化。
核心结构
- 迭代器接口(
Iterator
):定义遍历元素的方法(如hasNext()
、next()
、remove()
)。
- 具体迭代器(
Concrete Iterator
):实现迭代器接口,维护遍历的当前位置。
- 聚合接口(
Aggregate
):定义创建迭代器的方法(如createIterator()
)。
- 具体聚合(
Concrete Aggregate
):实现聚合接口,返回具体迭代器实例。
示例说明
场景:自定义数组的迭代器
- 定义迭代器接口
1 2 3 4 5 6 7 8
|
interface Iterator<T> { boolean hasNext(); T next(); void remove(); }
|
- 定义聚合接口
1 2 3 4 5
|
interface Aggregate<T> { Iterator<T> createIterator(); }
|
- 自定义实现一个数据实现聚合接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| class MyArray<T> implements Aggregate<T> { private T[] elements; private int size; public MyArray(int capacity) { elements = (T[]) new Object[capacity]; size = 0; } public void add(T element) { if (size < elements.length) { elements[size++] = element; } } public int getSize() { return size; } public T get(int index) { if (index >= 0 && index < size) { return elements[index]; } throw new IndexOutOfBoundsException(); } @Override public Iterator<T> createIterator() { return new ArrayIterator<>(this); } private class ArrayIterator<T> implements Iterator<T> { private MyArray<T> array; private int currentIndex = 0; public ArrayIterator(MyArray<T> array) { this.array = array; } @Override public boolean hasNext() { return currentIndex < array.getSize(); } @Override public T next() { if (hasNext()) { return array.get(currentIndex++); } throw new IllegalStateException("没有更多元素"); } @Override public void remove() { if (currentIndex > 0) { array.elements[currentIndex - 1] = null; array.size--; currentIndex--; } } } }
|
- 测试验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class Test { public static void main(String[] args) { MyArray<String> names = new MyArray<>(5); names.add("张三"); names.add("李四"); names.add("王五"); Iterator<String> iterator = names.createIterator(); System.out.println("使用迭代器遍历:"); while (iterator.hasNext()) { System.out.println(iterator.next()); } System.out.println("\n使用for-each遍历(Java内置迭代器支持):"); for (String name : names) { System.out.println(name); } } }
|
实现这个模式,给了一种遍历元素的而不知道事务在底层如何表达的方式。迭代器模式拿走了遍历元素的责任,把它交给迭代器对象而不是聚合对象。这不仅让聚合的接口和实现更加简单,它还从聚合移除了遍历的责任,让聚合专注于管理对象集合。
专门设计一个迭代器类,负责遍历集合的操作,这就涉及一个新的设计原则,单一职责原则:一个类应该只有一个变化的原因。这个原则指引我们,只把一个责任分配给一个类而且仅一个类
类图如下:

总结
优点
- 解耦遍历与集合:客户端无需知道集合内部结构,仅通过迭代器操作元素。
- 支持多种遍历方式:可针对同一集合创建不同迭代器(如正序、倒序、过滤遍历)。
- 符合单一职责:集合类专注于数据存储,迭代器专注于遍历逻辑。
- 简化集合接口:客户端无需暴露集合的索引或指针,提高安全性。
缺点
- 类数量增加:引入迭代器和聚合接口,可能导致类爆炸(但现代语言常内置支持)。
- 对内置支持的依赖:若语言原生支持迭代器(如Java的
Iterator
),自定义迭代器成本降低。
使用场景
需要统一遍历接口:不同集合(数组、链表、树)提供一致的遍历方式。
集合内部复杂:不想暴露集合的存储结构(如链表的节点指针)。
支持多种遍历逻辑:如文件系统遍历(按名称、按时间、按类型)。
惰性加载场景:迭代器可按需加载元素(如数据库查询的分页遍历)。
并行遍历需求:多个迭代器可同时遍历同一集合(需考虑线程安全)。
迭代器模式的核心是“分离遍历逻辑与数据存储”,就像超市的购物车——无论货架如何摆放(集合内部结构),顾客(客户端)只需通过购物车的把手(迭代器)按顺序挑选商品。这种模式在Java集合框架、文件IO、数据库查询等场景中使用较多。
通过迭代器,系统可更灵活地支持不同遍历策略,同时保证集合内部数据的封装性。