1. 迭代器模式:为什么我们需要它?
作为一名有十年经验的Java开发者,我至今还记得第一次面对多种集合类型遍历时的困惑。当时项目中同时使用了数组、ArrayList和自定义链表结构,每次遍历都要写不同的循环代码,不仅重复劳动,还经常因为不熟悉某种集合的内部实现而踩坑。直到学习了迭代器模式,才真正体会到设计模式的精妙之处。
迭代器模式的核心价值在于它提供了一种统一的遍历接口,让我们能够以相同的方式访问不同类型的集合对象。想象一下你去图书馆借书,不管书籍是按照分类摆放、字母顺序排列还是随机堆放,你只需要通过图书检索系统(迭代器)就能找到想要的书籍,而不需要了解书籍实际存放的物理结构。这就是迭代器模式的现实映射。
提示:迭代器模式特别适合以下场景:当你的系统需要处理多种数据结构,但希望对外提供一致的遍历接口时;或者当你希望隐藏集合内部复杂结构,只暴露必要的遍历功能时。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 迭代器模式原理深度解析
2.1 模式结构与组件职责
让我们通过一个完整的UML类图来理解迭代器模式的组成:
code复制+-------------------+ +-------------------+
| Aggregate | | Iterator |
+-------------------+ +-------------------+
| +createIterator() |<------>| +first() |
+-------------------+ | +next() |
^ | +isDone() |
| | +currentItem() |
| +-------------------+
| ^
| |
+-------------------+ +-------------------+
| ConcreteAggregate | | ConcreteIterator |
+-------------------+ +-------------------+
| +createIterator() |------->| +first() |
| +getItem() | | +next() |
| +getSize() | | +isDone() |
+-------------------+ | +currentItem() |
+-------------------+
在这个结构中,四个核心组件各司其职:
-
Aggregate(抽象聚合接口):
- 定义创建迭代器对象的接口
- 通常包含一个createIterator()方法
- 可能还包含获取集合大小、获取指定位置元素等方法
-
Iterator(抽象迭代器接口):
- 定义遍历集合的通用操作
- 基本方法包括:first()、next()、isDone()、currentItem()
- 有些实现也会使用hasNext()替代isDone()
-
ConcreteAggregate(具体聚合类):
- 实现Aggregate接口
- 负责创建并返回对应的具体迭代器实例
- 维护集合的实际数据存储
-
ConcreteIterator(具体迭代器类):
- 实现Iterator接口
- 跟踪遍历过程中的当前位置
- 实现对集合元素的实际访问逻辑
2.2 Java集合框架中的迭代器实现
Java集合框架是迭代器模式的经典应用。以ArrayList为例,我们来看它的迭代器实现:
java复制// ArrayList中的迭代器创建
public Iterator<E> iterator() {
return new Itr();
}
// 具体的Itr实现
private class Itr implements Iterator<E> {
int cursor; // 下一个要返回的元素的索引
int lastRet = -1; // 最后一个返回的元素的索引
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
// 其他方法省略...
}
这种实现有几个值得注意的设计点:
- 迭代器作为集合的内部类实现,可以直接访问外部类的私有成员
- 通过modCount机制实现快速失败(fail-fast)的并发修改检测
- 游标设计既简单又高效,适合数组结构的遍历
3. 迭代器模式实战:自定义集合实现
3.1 场景描述与需求分析
假设我们正在开发一个电商系统,需要处理三种商品集合:
- 数组存储的特价商品(性能考虑)
- **ArrayList存
