Skip to content

迭代器

更新: 6/22/2025 字数: 0 字 时长: 0 分钟

定义

迭代器模式 (Iterator Pattern) 提供一种方法顺序访问聚合对象中的各个元素,而又不暴露其内部表示。它分离了集合对象的遍历行为,使得可以在不暴露集合内部结构的情况下访问集合元素。

角色

  • 迭代器 (Iterator):定义访问和遍历元素的接口
  • 具体迭代器 (Concrete Iterator):实现迭代器接口,跟踪当前位置
  • 聚合 (Aggregate):定义创建迭代器对象的接口
  • 具体聚合 (Concrete Aggregate):实现创建迭代器对象的接口
  • 客户端 (Client):使用迭代器遍历聚合对象

实现

基础迭代器

java
// 迭代器接口
public interface Iterator<T> {
    boolean hasNext();
    T next();
    void remove();
}

// 聚合接口
public interface Aggregate<T> {
    Iterator<T> createIterator();
}

// 具体聚合:书柜
public class BookShelf implements Aggregate<Book> {
    private List<Book> books;
    
    public BookShelf() {
        this.books = new ArrayList<>();
    }
    
    public void addBook(Book book) {
        books.add(book);
    }
    
    @Override
    public Iterator<Book> createIterator() {
        return new BookShelfIterator(this);
    }
    
    public int size() {
        return books.size();
    }
    
    public Book getBookAt(int index) {
        return books.get(index);
    }
}

// 具体迭代器:书柜迭代器
public class BookShelfIterator implements Iterator<Book> {
    private BookShelf bookShelf;
    private int index;
    
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }
    
    @Override
    public boolean hasNext() {
        return index < bookShelf.size();
    }
    
    @Override
    public Book next() {
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
    
    @Override
    public void remove() {
        throw new UnsupportedOperationException("不支持删除操作");
    }
}

// 书对象
public class Book {
    private String name;
    
    public Book(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
}

// 客户端使用
public class IteratorDemo {
    public static void main(String[] args) {
        BookShelf shelf = new BookShelf();
        shelf.addBook(new Book("Design Patterns"));
        shelf.addBook(new Book("Clean Code"));
        shelf.addBook(new Book("Refactoring"));
        
        Iterator<Book> it = shelf.createIterator();
        while (it.hasNext()) {
            Book book = it.next();
            System.out.println(book.getName());
        }
    }
}

双向迭代器

java
// 双向迭代器接口
public interface BidirectionalIterator<T> extends Iterator<T> {
    boolean hasPrevious();
    T previous();
    void first();
    void last();
}

// 具体双向迭代器
public class BookShelfBidirectionalIterator implements BidirectionalIterator<Book> {
    private BookShelf bookShelf;
    private int index;
    
    public BookShelfBidirectionalIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
        this.index = 0;
    }
    
    @Override
    public boolean hasNext() {
        return index < bookShelf.size();
    }
    
    @Override
    public Book next() {
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
    
    @Override
    public boolean hasPrevious() {
        return index > 0;
    }
    
    @Override
    public Book previous() {
        index--;
        return bookShelf.getBookAt(index);
    }
    
    @Override
    public void first() {
        index = 0;
    }
    
    @Override
    public void last() {
        index = bookShelf.size() - 1;
    }
    
    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }
}

// 使用示例
public class BidirectionalIteratorDemo {
    public static void main(String[] args) {
        BookShelf shelf = new BookShelf();
        shelf.addBook(new Book("Effective Java"));
        shelf.addBook(new Book("Java Concurrency in Practice"));
        shelf.addBook(new Book("Java Performance"));
        
        BidirectionalIterator<Book> it = new BookShelfBidirectionalIterator(shelf);
        
        System.out.println("正向遍历:");
        while (it.hasNext()) {
            System.out.println(it.next().getName());
        }
        
        System.out.println("\n反向遍历:");
        while (it.hasPrevious()) {
            System.out.println(it.previous().getName());
        }
        
        System.out.println("\n跳到最后:");
        it.last();
        System.out.println(it.previous().getName());
    }
}

优缺点

优点:

  1. 支持多种遍历方式
  2. 简化聚合接口
  3. 支持并行迭代
  4. 符合单一职责原则
  5. 符合开闭原则
  6. 隐藏聚合内部结构

缺点:

  1. 增加系统复杂度
  2. 性能可能略低于直接遍历
  3. 某些语言已有内置迭代器
  4. 实现线程安全迭代器较复杂

应用场景

  1. 集合框架遍历(Java Collections)
  2. 树形结构遍历
  3. 文件系统遍历
  4. 数据库结果集遍历
  5. 图结构遍历
  6. 分页查询实现
  7. 流式数据处理

与其他模式的关系

  • 与组合模式:迭代器常用于遍历组合结构
  • 与工厂方法模式:聚合通常使用工厂方法创建迭代器
  • 与备忘录模式:配合实现迭代状态保存
  • 与访问者模式:迭代器遍历元素,访问者执行操作
  • 与策略模式:可更换不同的迭代算法

JDK 中的迭代器模式

  1. Java 集合框架(Iterator, ListIterator)
  2. Java NIO 文件遍历(DirectoryStream)
  3. JDBC 结果集(ResultSet)
  4. XML 解析(SAX 解析器)
  5. Java Stream API
  6. Java 枚举(Enumeration)
  7. Spring 资源遍历(ResourcePatternResolver)

注意事项

  1. 迭代器线程安全问题
  2. 迭代过程中修改集合问题
  3. 空迭代器处理
  4. 迭代器资源释放
  5. 支持并发迭代
  6. 考虑迭代性能优化
  7. 设计完备的迭代器接口

贡献者

The avatar of contributor named as LI SIR LI SIR
The avatar of contributor named as wkwbk wkwbk

页面历史