java23种设计模式-迭代器模式

发布于:2025-02-28 ⋅ 阅读:(19) ⋅ 点赞:(0)

迭代器模式(Iterator Pattern)学习笔记


编程相关书籍分享:https://blog.csdn.net/weixin_47763579/article/details/145855793


1. 模式定义

行为型设计模式,提供一种方法顺序访问聚合对象中的各个元素,而无需暴露该对象的内部表示。将遍历逻辑与聚合对象解耦,实现多种遍历方式。

2. 适用场景

✅ 需要统一遍历不同结构的聚合对象
✅ 需要支持多种遍历方式(正序/逆序/过滤等)
✅ 需要隐藏聚合对象的内部结构
✅ 需要为同一聚合对象提供多个并行遍历
✅ 遵循单一职责原则(分离遍历职责)

3. 模式结构

creates
«interface»
Aggregate
+createIterator() : Iterator
ConcreteAggregate
-items: List
+createIterator()
«interface»
Iterator
+hasNext() : boolean
+next() : Object
+remove()
ConcreteIterator
-aggregate: ConcreteAggregate
-index: int
+hasNext()
+next()
Client
+traverse()

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. 模式变种

  1. 内部迭代器
    将迭代逻辑封装在聚合内部,客户端通过回调函数操作元素

    public interface InternalIterator {
        void forEach(Consumer<Book> action);
    }
    
    // 客户端调用
    bookShelf.forEach(book -> System.out.println(book));
    
  2. 过滤迭代器
    实现条件遍历功能

    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. 最佳实践建议

  1. 优先使用现有迭代器:Java集合的Iterator已足够应对多数场景
  2. 实现Iterable接口:方便与增强for循环集成
    public class BookShelf implements Iterable<Book> {
        // ...
        public Iterator<Book> iterator() {
            return new BookIterator(this);
        }
    }
    
  3. 支持快速失败(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();
            }
        }
    }
    
  4. 使用泛型:增强类型安全性
  5. 考虑线程安全:同步访问或返回独立迭代器
  6. 组合使用其他模式:如工厂方法创建迭代器

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;
    }
}

🔄 设计原则体现

  1. 单一职责原则:将遍历职责从集合类中分离
  2. 开闭原则:新增迭代器无需修改现有代码
  3. 接口隔离原则:客户端仅依赖迭代器接口

通过迭代器模式,可以实现灵活的集合遍历机制,特别适合需要支持多种遍历方式或隐藏集合内部结构的场景。该模式在集合框架和复杂数据结构处理中应用广泛,是解耦遍历逻辑的经典解决方案。