Java行为型模式---迭代器模式
迭代器模式基础概念
迭代器模式(Iterator Pattern)是一种行为型设计模式,其核心思想是提供一种方法顺序访问聚合对象(如集合、列表等)中的元素,而无需暴露该对象的内部表示。迭代器模式将遍历逻辑与聚合对象分离,使聚合对象的结构和遍历算法可以独立变化。
迭代器模式的核心组件
- 迭代器接口(Iterator) - 定义访问和遍历元素的接口,包含
hasNext()
(是否有下一个元素)和next()
(获取下一个元素)等方法。 - 具体迭代器(ConcreteIterator) - 实现迭代器接口,负责跟踪当前遍历位置,完成具体的遍历逻辑。
- 聚合接口(Aggregate) - 定义创建迭代器对象的接口,通常包含
createIterator()
方法。 - 具体聚合(ConcreteAggregate) - 实现聚合接口,返回具体迭代器的实例,同时存储和管理元素。
- 客户端(Client) - 通过聚合接口获取迭代器,再使用迭代器遍历元素,无需关心聚合对象的内部结构。
迭代器模式的实现
import java.util.ArrayList;
import java.util.List;// 1. 迭代器接口
interface Iterator {boolean hasNext();Object next();
}// 2. 聚合接口
interface Aggregate {Iterator createIterator();
}// 3. 具体迭代器(遍历自定义列表)
class ConcreteIterator implements Iterator {private final List<String> items; // 聚合对象的元素private int position = 0; // 当前遍历位置public ConcreteIterator(List<String> items) {this.items = items;}@Overridepublic boolean hasNext() {// 判断是否还有下一个元素return position < items.size();}@Overridepublic Object next() {// 返回当前元素并移动到下一个位置if (this.hasNext()) {return items.get(position++);}return null;}
}// 4. 具体聚合(自定义列表)
class ConcreteAggregate implements Aggregate {private final List<String> items = new ArrayList<>();public void addItem(String item) {items.add(item);}public void removeItem(String item) {items.remove(item);}@Overridepublic Iterator createIterator() {// 返回迭代器实例,关联当前聚合对象的元素return new ConcreteIterator(items);}
}// 5. 客户端代码
public class IteratorPatternClient {public static void main(String[] args) {// 创建聚合对象并添加元素ConcreteAggregate aggregate = new ConcreteAggregate();aggregate.addItem("Item 1");aggregate.addItem("Item 2");aggregate.addItem("Item 3");aggregate.addItem("Item 4");// 获取迭代器并遍历元素Iterator iterator = aggregate.createIterator();System.out.println("遍历聚合对象元素:");while (iterator.hasNext()) {String item = (String) iterator.next();System.out.println(item);}}
}
Java 内置迭代器的应用
Java 集合框架(java.util
)广泛使用了迭代器模式,Iterator
接口是迭代器模式的典型实现。以下是 Java 内置迭代器的使用示例:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class JavaIteratorExample {public static void main(String[] args) {List<String> fruits = new ArrayList<>();fruits.add("Apple");fruits.add("Banana");fruits.add("Orange");// 获取迭代器Iterator<String> iterator = fruits.iterator();// 遍历元素System.out.println("Java内置迭代器遍历:");while (iterator.hasNext()) {String fruit = iterator.next();System.out.println(fruit);// 迭代过程中可以安全删除元素if (fruit.equals("Banana")) {iterator.remove();}}System.out.println("删除后的列表:" + fruits); // [Apple, Orange]}
}
Java 迭代器的核心方法:
hasNext()
:判断是否有下一个元素next()
:返回当前元素并移动到下一个位置remove()
:删除next()
返回的最后一个元素(可选操作)
迭代器模式的应用场景
- 聚合对象遍历 - 如列表、集合、树等复杂数据结构的遍历
- 隐藏内部结构 - 不希望暴露聚合对象的内部实现(如数组、链表等)
- 多种遍历方式 - 一个聚合对象需要支持多种遍历方式(如正序、倒序、过滤遍历)
- 统一遍历接口 - 对不同类型的聚合对象(如数组、链表、哈希表)提供统一的遍历接口
- 迭代中操作安全 - 需要在遍历过程中安全地添加 / 删除元素(如 Java 迭代器的
remove()
方法)
迭代器模式的优缺点
优点:
- 解耦遍历与聚合 - 遍历逻辑与聚合对象分离,各自可独立变化
- 统一遍历接口 - 不同聚合对象可以通过相同的迭代器接口遍历
- 支持多种遍历方式 - 一个聚合对象可以有多个迭代器实现不同的遍历逻辑
- 简化客户端代码 - 客户端无需了解聚合对象的内部结构即可遍历
- 符合单一职责原则 - 聚合对象负责存储数据,迭代器负责遍历数据
缺点:
- 类数量增加 - 每个聚合对象可能需要对应一个迭代器,增加系统复杂度
- 遍历效率问题 - 某些迭代器(如链表的随机访问迭代器)可能效率较低
- 迭代器状态依赖 - 迭代器依赖聚合对象的状态,聚合对象修改可能导致迭代器失效
- 双向迭代复杂 - 实现双向迭代器(支持
previous()
)会增加设计难度
迭代器模式的扩展
双向迭代器(Bidirectional Iterator) - 支持向前和向后遍历(如
ListIterator
):interface BidirectionalIterator extends Iterator {boolean hasPrevious();Object previous(); }
跳跃迭代器(Jump Iterator) - 支持跳过部分元素(如间隔 n 个元素遍历):
interface JumpIterator extends Iterator {Object jump(int steps); // 跳过steps个元素 }
过滤迭代器(Filter Iterator) - 只遍历符合条件的元素:
class FilterIterator implements Iterator {private final Iterator iterator;private final Predicate filter; // 过滤条件// 实现略... }
使用迭代器模式的注意事项
- 迭代器的线程安全 - 多线程环境下,迭代器需要考虑线程安全(如使用同步或并发迭代器)
- 避免迭代中修改聚合对象 - 多数迭代器不支持遍历中修改聚合对象(会抛出
ConcurrentModificationException
) - 合理设计迭代器生命周期 - 迭代器应与聚合对象的生命周期匹配,避免无效引用
- 优先使用内置迭代器 - Java 集合框架已实现完善的迭代器,无需重复造轮子
- 结合 foreach 循环 - Java 5 + 的增强 for 循环(foreach)本质上是迭代器的语法糖,可简化代码
总结
迭代器模式通过分离聚合对象的存储逻辑和遍历逻辑,实现了代码的解耦和复用。它在 Java 集合框架中应用广泛,是处理集合遍历的标准方式。合理使用迭代器模式可以简化客户端代码,隐藏聚合对象的内部结构,并支持灵活的遍历方式。在实际开发中,除非需要自定义聚合结构或特殊遍历逻辑,否则优先使用 Java 内置的Iterator
接口及其实现。