迭代器模式(Iterator Pattern)学习笔记
编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793
1. 模式定义
行为型设计模式,提供一种方法顺序访问聚合对象中的各个元素,而无需暴露该对象的内部表示。将遍历逻辑与聚合对象解耦,实现多种遍历方式。
2. 适用场景
✅ 需要统一遍历不同结构的聚合对象
✅ 需要支持多种遍历方式(正序/逆序/过滤等)
✅ 需要隐藏聚合对象的内部结构
✅ 需要为同一聚合对象提供多个并行遍历
✅ 遵循单一职责原则(分离遍历职责)
3. 模式结构
4. 核心角色
角色 | 说明 |
---|---|
Aggregate | 聚合接口,定义创建迭代器的方法 |
ConcreteAggregate | 具体聚合类,实现创建对应迭代器 |
Iterator | 迭代器接口,定义遍历方法 |
ConcreteIterator | 具体迭代器,实现遍历逻辑 |
Client | 客户端,通过迭代器访问聚合对象 |
5. 代码示例
5.1 书架遍历示例
// 聚合接口
public interface BookShelf {
Iterator<Book> iterator();
void addBook(Book book);
}
// 具体聚合
public class ConcreteBookShelf implements BookShelf {
private List<Book> books = new ArrayList<>();
public Iterator<Book> iterator() {
return new BookIterator(this);
}
public void addBook(Book book) {
books.add(book);
}
public int size() {
return books.size();
}
public Book getAt(int index) {
return books.get(index);
}
}
// 迭代器接口
public interface Iterator<T> {
boolean hasNext();
T next();
}
// 具体迭代器
public class BookIterator implements Iterator<Book> {
private ConcreteBookShelf bookShelf;
private int index = 0;
public BookIterator(ConcreteBookShelf bookShelf) {
this.bookShelf = bookShelf;
}
public boolean hasNext() {
return index < bookShelf.size();
}
public Book next() {
Book book = bookShelf.getAt(index);
index++;
return book;
}
}
// 客户端
public class Client {
public static void main(String[] args) {
BookShelf shelf = new ConcreteBookShelf();
shelf.addBook(new Book("Design Patterns"));
shelf.addBook(new Book("Clean Code"));
shelf.addBook(new Book("Refactoring"));
Iterator<Book> it = shelf.iterator();
while(it.hasNext()) {
System.out.println(it.next().getTitle());
}
}
}
class Book {
private String title;
public Book(String title) { this.title = title; }
public String getTitle() { return title; }
}
6. 模式变种
内部迭代器:
将迭代逻辑封装在聚合内部,客户端通过回调函数操作元素public interface InternalIterator { void forEach(Consumer<Book> action); } // 客户端调用 bookShelf.forEach(book -> System.out.println(book));
过滤迭代器:
实现条件遍历功能public class FilterIterator implements Iterator<Book> { private Iterator<Book> source; private Predicate<Book> predicate; public FilterIterator(Iterator<Book> source, Predicate<Book> predicate) { this.source = source; this.predicate = predicate; } public boolean hasNext() { while(source.hasNext()) { if(predicate.test(source.next())) return true; } return false; } // 实现next()... }
7. 优缺点分析
✔️ 优点:
- 分离集合对象与遍历算法
- 支持多种遍历方式
- 简化聚合接口
- 支持并行遍历
- 符合单一职责和开闭原则
❌ 缺点:
- 增加系统复杂度(简单集合可能不需要)
- 遍历效率可能低于直接访问
- 需要维护迭代器状态
8. 相关模式对比
模式 | 目的 | 关键区别 |
---|---|---|
访问者模式 | 对对象结构元素执行操作 | 迭代器关注遍历,访问者关注操作 |
组合模式 | 处理树形结构 | 常与迭代器模式结合使用 |
工厂方法模式 | 创建对象 | 迭代器常使用工厂方法创建具体迭代器 |
9. 实际应用案例
- Java集合框架的
Iterator
接口 - JDBC的
ResultSet
遍历 - XML解析器的节点遍历(DOM4J的NodeIterator)
- Android的
Cursor
接口 - Spring的
ResourceArrayPropertyEditor
- MyBatis的
Cursor
接口(流式查询)
10. 最佳实践建议
- 优先使用现有迭代器:Java集合的
Iterator
已足够应对多数场景 - 实现
Iterable
接口:方便与增强for循环集成public class BookShelf implements Iterable<Book> { // ... public Iterator<Book> iterator() { return new BookIterator(this); } }
- 支持快速失败(fail-fast):检测并发修改
public class SafeIterator implements Iterator<Book> { private int modCount = expectedModCount; public boolean hasNext() { checkModification(); // ... } private void checkModification() { if(modCount != expectedModCount) { throw new ConcurrentModificationException(); } } }
- 使用泛型:增强类型安全性
- 考虑线程安全:同步访问或返回独立迭代器
- 组合使用其他模式:如工厂方法创建迭代器
11. 扩展应用(树形结构遍历)
// 树节点
class TreeNode {
String value;
List<TreeNode> children = new ArrayList<>();
public Iterator<TreeNode> depthFirstIterator() {
return new DepthFirstIterator(this);
}
public Iterator<TreeNode> breadthFirstIterator() {
return new BreadthFirstIterator(this);
}
}
// 深度优先迭代器
class DepthFirstIterator implements Iterator<TreeNode> {
private Stack<TreeNode> stack = new Stack<>();
public DepthFirstIterator(TreeNode root) {
stack.push(root);
}
public boolean hasNext() {
return !stack.isEmpty();
}
public TreeNode next() {
TreeNode current = stack.pop();
for(int i = current.children.size()-1; i >=0; i--) {
stack.push(current.children.get(i));
}
return current;
}
}
// 广度优先迭代器
class BreadthFirstIterator implements Iterator<TreeNode> {
private Queue<TreeNode> queue = new LinkedList<>();
public BreadthFirstIterator(TreeNode root) {
queue.offer(root);
}
public boolean hasNext() {
return !queue.isEmpty();
}
public TreeNode next() {
TreeNode current = queue.poll();
queue.addAll(current.children);
return current;
}
}
🔄 设计原则体现:
- 单一职责原则:将遍历职责从集合类中分离
- 开闭原则:新增迭代器无需修改现有代码
- 接口隔离原则:客户端仅依赖迭代器接口
通过迭代器模式,可以实现灵活的集合遍历机制,特别适合需要支持多种遍历方式或隐藏集合内部结构的场景。该模式在集合框架和复杂数据结构处理中应用广泛,是解耦遍历逻辑的经典解决方案。