你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号“吴计可师”,已经更新了近百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞
迭代器模式详解
一、定义与核心思想
迭代器模式(Iterator Pattern) 是一种行为型设计模式,提供一种方法顺序访问聚合对象(如集合)中的元素,无需暴露其底层表示。核心思想在于解耦遍历逻辑与数据结构,让客户端能够以统一的方式处理不同类型的集合。
二、适用场景
- 统一遍历接口:对数组、链表、树等不同结构的集合提供一致的访问方式。
- 隐藏集合实现:避免客户端依赖具体集合类内部结构。
- 支持多种遍历方式:如正序、逆序、过滤遍历。
- 简化聚合接口:将遍历职责分离到迭代器中,聚合类更专注数据存储。
三、模式结构
| 角色 | 职责 |
|---|---|
| 迭代器接口(Iterator) | 定义遍历方法(hasNext(), next())。 |
| 具体迭代器(Concrete Iterator) | 实现特定集合的遍历逻辑(如ArrayIterator)。 |
| 聚合接口(Aggregate) | 定义创建迭代器的方法(createIterator())。 |
| 具体聚合类(Concrete Aggregate) | 存储数据并返回对应迭代器(如BookShelf)。 |
四、实现示例:书籍集合遍历
// 书籍类
public class Book {
private String name;
public Book(String name) { this.name = name; }
public String getName() { return name; }
}
// 迭代器接口
public interface Iterator<T> {
boolean hasNext();
T next();
}
// 具体迭代器(数组)
public class ArrayIterator<T> implements Iterator<T> {
private T[] array;
private int index = 0;
public ArrayIterator(T[] array) {
this.array = array;
}
@Override
public boolean hasNext() {
return index < array.length;
}
@Override
public T next() {
if (hasNext()) {
return array[index++];
}
throw new NoSuchElementException();
}
}
// 聚合接口
public interface Aggregate<T> {
Iterator<T> createIterator();
}
// 具体聚合类(书架)
public class BookShelf implements Aggregate<Book> {
private Book[] books;
public BookShelf(Book[] books) {
this.books = books;
}
@Override
public Iterator<Book> createIterator() {
return new ArrayIterator<>(books);
}
}
// 客户端使用
Book[] books = {new Book("设计模式"), new Book("算法导论")};
BookShelf shelf = new BookShelf(books);
Iterator<Book> it = shelf.createIterator();
while (it.hasNext()) {
System.out.println(it.next().getName());
}
// 输出:
// 设计模式
// 算法导论
五、核心优势
- 单一职责原则:集合类管理数据存储,迭代器类管理遍历逻辑。
- 开闭原则:新增集合类型或迭代方式无需修改现有代码。
- 多线程支持:可为同一集合创建多个独立迭代器,各自维护遍历状态。
- 延迟加载:按需获取元素(如数据库分页查询)。
六、应用案例
- Java集合框架:
java.util.Iterator接口与List.iterator()方法。 - 文件系统遍历:递归遍历目录树。
- 数据库查询结果集:逐行读取查询结果。
- 图结构遍历:BFS/DFS算法封装为迭代器。
七、Java内置迭代器
1. 标准用法
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
2. 快速失败(Fail-Fast)机制
- 检测并发修改:
List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3)); Iterator<Integer> it = list.iterator(); list.add(4); // 修改集合 it.next(); // 抛出ConcurrentModificationException
3. 自定义迭代器
public class EvenIterator implements Iterator<Integer> {
private List<Integer> list;
private int currentIndex = 0;
public EvenIterator(List<Integer> list) {
this.list = list;
}
@Override
public boolean hasNext() {
while (currentIndex < list.size()) {
if (list.get(currentIndex) % 2 == 0) return true;
currentIndex++;
}
return false;
}
@Override
public Integer next() {
if (!hasNext()) throw new NoSuchElementException();
return list.get(currentIndex++);
}
}
// 使用
List<Integer> nums = Arrays.asList(1,2,3,4);
Iterator<Integer> it = new EvenIterator(nums);
while (it.hasNext()) {
System.out.println(it.next()); // 输出2,4
}
八、与其他模式对比
| 模式 | 核心差异 |
|---|---|
| 访问者模式 | 将算法与数据结构分离;迭代器专注遍历。 |
| 组合模式 | 管理树形结构;迭代器遍历树节点。 |
| 工厂方法模式 | 用于创建迭代器对象。 |
九、注意事项
- 性能开销:复杂迭代器(如树遍历)可能影响性能。
- 过犹不及:简单集合(如数组)直接遍历更高效。
- 不可逆操作:标准迭代器通常不支持逆向遍历或修改集合。
十、总结
迭代器模式通过抽象遍历逻辑,为异构数据结构的统一访问提供了优雅方案。其核心价值在于:
- 解耦客户端与集合实现,提升代码可维护性。
- 支持灵活的遍历策略,扩展性强。
- 简化聚合类接口,符合单一职责原则。
在需要处理多种数据结构或提供复杂遍历逻辑的场景中,迭代器模式是提升代码质量的利器。
今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复“进群”,可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师