迭代器设计模式全方位深度解析

7 阅读8分钟

一、设计模式概述

1.1 核心思想

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。它将遍历集合的责任与集合对象本身分离,使集合可以专注于存储数据,而遍历逻辑由专门的迭代器对象处理。

1.2 UML类图结构

复制
┌─────────────┐          ┌─────────────┐
│  Iterator   │<---------│Aggregate    │
├─────────────┤          ├─────────────┤
│+first()     │          │+createIterator()│
│+next()      │          └─────────────┘
│+isDone()    │                  △
│+currentItem()│                 │
└─────────────┘          ┌───────┴───────┐
         △               │               │
         │         ┌─────────┐   ┌─────────┐
         │         │Concrete │   │Concrete │
         │         │Aggregate│   │Iterator │
         │         └─────────┘   └─────────┘
┌─────────────┐          │               │
│  Client     │─────────>│               │
└─────────────┘          └───────────────┘

二、完整Java代码实现

2.1 基本迭代器模式实现

java
java
下载
复制
// 1. 迭代器接口
interface Iterator<T> {
    boolean hasNext();
    T next();
    void remove();
}

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

// 3. 具体聚合类
class Book {
    private String name;
    private String author;
    
    public Book(String name, String author) {
        this.name = name;
        this.author = author;
    }
    
    public String getName() { return name; }
    public String getAuthor() { return author; }
    
    @Override
    public String toString() {
        return "《" + name + "》 - " + author;
    }
}

class BookShelf implements Aggregate<Book> {
    private List<Book> books = new ArrayList<>();
    private int capacity = 10;
    
    public BookShelf() {}
    
    public BookShelf(int capacity) {
        this.capacity = capacity;
    }
    
    public Book getBookAt(int index) {
        if (index < 0 || index >= books.size()) {
            throw new IndexOutOfBoundsException();
        }
        return books.get(index);
    }
    
    public void appendBook(Book book) {
        if (books.size() >= capacity) {
            throw new IllegalStateException("书架已满");
        }
        books.add(book);
    }
    
    public int getLength() {
        return books.size();
    }
    
    @Override
    public Iterator<Book> createIterator() {
        return new BookShelfIterator(this);
    }
}

// 4. 具体迭代器实现
class BookShelfIterator implements Iterator<Book> {
    private BookShelf bookShelf;
    private int index = 0;
    
    public BookShelfIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
    }
    
    @Override
    public boolean hasNext() {
        return index < bookShelf.getLength();
    }
    
    @Override
    public Book next() {
        if (!hasNext()) {
            throw new NoSuchElementException("没有更多元素");
        }
        Book book = bookShelf.getBookAt(index);
        index++;
        return book;
    }
    
    @Override
    public void remove() {
        // 简化实现,实际中需要修改底层集合
        throw new UnsupportedOperationException("不支持remove操作");
    }
}

// 5. 客户端使用
public class IteratorDemo {
    public static void main(String[] args) {
        BookShelf bookShelf = new BookShelf(5);
        bookShelf.appendBook(new Book("设计模式", "四人组"));
        bookShelf.appendBook(new Book("Java编程思想", "Bruce Eckel"));
        bookShelf.appendBook(new Book("代码大全", "Steve McConnell"));
        
        // 使用迭代器遍历
        Iterator<Book> iterator = bookShelf.createIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

2.2 双向迭代器实现

java
java
下载
复制
// 双向迭代器接口
interface BidirectionalIterator<T> extends Iterator<T> {
    boolean hasPrevious();
    T previous();
    void goToFirst();
    void goToLast();
}

// 双向迭代器实现
class BidirectionalBookIterator implements BidirectionalIterator<Book> {
    private BookShelf bookShelf;
    private int index = 0;
    
    public BidirectionalBookIterator(BookShelf bookShelf) {
        this.bookShelf = bookShelf;
    }
    
    @Override
    public boolean hasNext() {
        return index < bookShelf.getLength();
    }
    
    @Override
    public Book next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        return bookShelf.getBookAt(index++);
    }
    
    @Override
    public boolean hasPrevious() {
        return index > 0;
    }
    
    @Override
    public Book previous() {
        if (!hasPrevious()) {
            throw new NoSuchElementException();
        }
        return bookShelf.getBookAt(--index);
    }
    
    @Override
    public void goToFirst() {
        index = 0;
    }
    
    @Override
    public void goToLast() {
        index = bookShelf.getLength() - 1;
    }
    
    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }
}

2.3 Java集合框架中的迭代器

java
java
下载
复制
// Java内置迭代器示例
public class JavaIteratorExample {
    public static void main(String[] args) {
        // List的迭代器
        List<String> list = Arrays.asList("A", "B", "C");
        
        // 1. 普通迭代器
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        
        // 2. ListIterator(双向迭代器)
        ListIterator<String> listIterator = list.listIterator();
        while (listIterator.hasNext()) {
            String item = listIterator.next();
            if (item.equals("B")) {
                listIterator.set("B2");  // 修改当前元素
                listIterator.add("B1.5");  // 添加元素
            }
        }
        
        // 3. 增强for循环(底层使用迭代器)
        for (String item : list) {
            System.out.println(item);
        }
        
        // 4. 流式迭代
        list.stream()
            .filter(s -> s.startsWith("A"))
            .forEach(System.out::println);
    }
}

2.4 泛型迭代器工厂

java
java
下载
复制
// 泛型迭代器工厂模式
interface IterableCollection<T> {
    Iterator<T> iterator();
    Iterator<T> reverseIterator();
    Iterator<T> randomIterator();
}

class GenericCollection<T> implements IterableCollection<T> {
    private List<T> items = new ArrayList<>();
    
    public void add(T item) {
        items.add(item);
    }
    
    @Override
    public Iterator<T> iterator() {
        return new ForwardIterator();
    }
    
    @Override
    public Iterator<T> reverseIterator() {
        return new ReverseIterator();
    }
    
    @Override
    public Iterator<T> randomIterator() {
        return new RandomIterator();
    }
    
    // 正向迭代器
    private class ForwardIterator implements Iterator<T> {
        private int currentIndex = 0;
        
        @Override
        public boolean hasNext() {
            return currentIndex < items.size();
        }
        
        @Override
        public T next() {
            if (!hasNext()) throw new NoSuchElementException();
            return items.get(currentIndex++);
        }
    }
    
    // 反向迭代器
    private class ReverseIterator implements Iterator<T> {
        private int currentIndex = items.size() - 1;
        
        @Override
        public boolean hasNext() {
            return currentIndex >= 0;
        }
        
        @Override
        public T next() {
            if (!hasNext()) throw new NoSuchElementException();
            return items.get(currentIndex--);
        }
    }
    
    // 随机迭代器
    private class RandomIterator implements Iterator<T> {
        private List<Integer> indices = new ArrayList<>();
        private int current = 0;
        
        public RandomIterator() {
            for (int i = 0; i < items.size(); i++) {
                indices.add(i);
            }
            Collections.shuffle(indices);
        }
        
        @Override
        public boolean hasNext() {
            return current < indices.size();
        }
        
        @Override
        public T next() {
            if (!hasNext()) throw new NoSuchElementException();
            return items.get(indices.get(current++));
        }
    }
}

三、应用场景分析

3.1 文件系统遍历

java
java
下载
复制
// 文件系统迭代器
class FileSystemIterator implements Iterator<File> {
    private Queue<File> queue = new LinkedList<>();
    
    public FileSystemIterator(File root) {
        if (root.exists() && root.isDirectory()) {
            queue.offer(root);
        }
    }
    
    @Override
    public boolean hasNext() {
        return !queue.isEmpty();
    }
    
    @Override
    public File next() {
        if (!hasNext()) throw new NoSuchElementException();
        
        File current = queue.poll();
        if (current.isDirectory()) {
            File[] files = current.listFiles();
            if (files != null) {
                for (File file : files) {
                    queue.offer(file);
                }
            }
        }
        return current;
    }
}

3.2 数据库查询结果遍历

java
java
下载
复制
// 数据库结果集迭代器
class DatabaseResultIterator implements Iterator<Map<String, Object>> {
    private ResultSet resultSet;
    private boolean hasNext = false;
    
    public DatabaseResultIterator(ResultSet resultSet) {
        this.resultSet = resultSet;
        try {
            hasNext = resultSet.next();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    
    @Override
    public boolean hasNext() {
        return hasNext;
    }
    
    @Override
    public Map<String, Object> next() {
        if (!hasNext) throw new NoSuchElementException();
        
        try {
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            Map<String, Object> row = new HashMap<>();
            
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i);
                Object value = resultSet.getObject(i);
                row.put(columnName, value);
            }
            
            hasNext = resultSet.next();
            return row;
            
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

3.3 实际应用场景

  1. 集合框架​ - Java Collections Framework (ArrayList, HashSet等)
  2. 数据库访问​ - 遍历查询结果集
  3. 文件系统​ - 递归遍历目录结构
  4. 树结构遍历​ - 二叉树、多叉树的前序/中序/后序遍历
  5. 图遍历​ - BFS、DFS算法实现
  6. 分页查询​ - 大数据量分页遍历
  7. 流式处理​ - 大数据流处理

四、优缺点深度分析

4.1 优点

单一职责原则:将遍历算法与集合对象分离

开闭原则:可以新增迭代器类型而无需修改集合

多线程友好:可为每个线程创建独立的迭代器

延迟计算:支持流式处理和惰性求值

多种遍历方式:同一集合可支持多种遍历方式

隐藏实现细节:客户端无需知道集合内部结构

4.2 缺点

复杂度增加:简单集合使用迭代器可能过于复杂

性能开销:迭代器对象创建和方法调用的开销

并发修改问题:遍历时修改集合可能导致异常

资源管理:需要确保迭代器正确关闭(如数据库连接)

不可逆操作:某些迭代器不支持回退操作

五、改进与优化方向

5.1 懒加载迭代器

java
java
下载
复制
// 支持延迟加载的迭代器
class LazyLoadingIterator<T> implements Iterator<T> {
    private final Supplier<Optional<T>> dataFetcher;
    private Optional<T> nextItem = Optional.empty();
    private boolean fetched = false;
    
    public LazyLoadingIterator(Supplier<Optional<T>> dataFetcher) {
        this.dataFetcher = dataFetcher;
    }
    
    @Override
    public boolean hasNext() {
        if (!fetched) {
            nextItem = dataFetcher.get();
            fetched = true;
        }
        return nextItem.isPresent();
    }
    
    @Override
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        T result = nextItem.get();
        fetched = false;
        return result;
    }
}

5.2 可组合迭代器

java
java
下载
复制
// 组合多个迭代器
class CompositeIterator<T> implements Iterator<T> {
    private final List<Iterator<T>> iterators = new ArrayList<>();
    private int currentIndex = 0;
    
    public void addIterator(Iterator<T> iterator) {
        iterators.add(iterator);
    }
    
    @Override
    public boolean hasNext() {
        if (iterators.isEmpty()) return false;
        
        // 跳过已耗尽的迭代器
        while (currentIndex < iterators.size() && !iterators.get(currentIndex).hasNext()) {
            currentIndex++;
        }
        return currentIndex < iterators.size();
    }
    
    @Override
    public T next() {
        if (!hasNext()) throw new NoSuchElementException();
        return iterators.get(currentIndex).next();
    }
}

5.3 线程安全的迭代器

java
java
下载
复制
// 快照迭代器(线程安全)
class SnapshotIterator<T> implements Iterator<T> {
    private final List<T> snapshot;
    private int currentIndex = 0;
    
    public SnapshotIterator(Collection<T> originalCollection) {
        // 创建集合的快照副本
        this.snapshot = new ArrayList<>(originalCollection);
    }
    
    @Override
    public boolean hasNext() {
        return currentIndex < snapshot.size();
    }
    
    @Override
    public T next() {
        if (!hasNext()) throw new NoSuchElementException();
        return snapshot.get(currentIndex++);
    }
}

5.4 支持过滤的迭代器

java
java
下载
复制
// 过滤迭代器
class FilteringIterator<T> implements Iterator<T> {
    private final Iterator<T> sourceIterator;
    private final Predicate<T> filter;
    private T nextItem = null;
    private boolean hasNextItem = false;
    
    public FilteringIterator(Iterator<T> sourceIterator, Predicate<T> filter) {
        this.sourceIterator = sourceIterator;
        this.filter = filter;
        findNext();
    }
    
    private void findNext() {
        while (sourceIterator.hasNext()) {
            T item = sourceIterator.next();
            if (filter.test(item)) {
                nextItem = item;
                hasNextItem = true;
                return;
            }
        }
        hasNextItem = false;
        nextItem = null;
    }
    
    @Override
    public boolean hasNext() {
        return hasNextItem;
    }
    
    @Override
    public T next() {
        if (!hasNext()) throw new NoSuchElementException();
        T result = nextItem;
        findNext();
        return result;
    }
}

六、注意事项与最佳实践

6.1 并发修改问题处理

java
java
下载
复制
// 失败快速迭代器
class FailFastIterator<T> implements Iterator<T> {
    private final List<T> list;
    private int cursor = 0;
    private int expectedModCount;
    
    public FailFastIterator(List<T> list) {
        this.list = list;
        this.expectedModCount = getModCount();
    }
    
    private int getModCount() {
        // 实际实现中,modCount是列表的修改计数器
        return 0; // 简化实现
    }
    
    @Override
    public boolean hasNext() {
        checkForComodification();
        return cursor < list.size();
    }
    
    @Override
    public T next() {
        checkForComodification();
        if (!hasNext()) throw new NoSuchElementException();
        return list.get(cursor++);
    }
    
    private void checkForComodification() {
        if (getModCount() != expectedModCount) {
            throw new ConcurrentModificationException(
                "集合在迭代过程中被修改");
        }
    }
}

6.2 内存优化迭代器

java
java
下载
复制
// 轻量级迭代器(适用于大型集合)
class LightweightIterator<T> implements Iterator<T> {
    private final T[] array;
    private int index = 0;
    
    public LightweightIterator(T[] array) {
        this.array = array;
    }
    
    @Override
    public boolean hasNext() {
        return index < array.length;
    }
    
    @Override
    public T next() {
        if (!hasNext()) throw new NoSuchElementException();
        return array[index++];
    }
    
    // 静态工厂方法,避免额外对象创建
    public static <T> LightweightIterator<T> of(T[] array) {
        return new LightweightIterator<>(array);
    }
}

6.3 Java 8+ Stream API集成

java
java
下载
复制
// 自定义迭代器适配为Stream
class StreamableCollection<T> implements Iterable<T> {
    private final Collection<T> items;
    
    public StreamableCollection(Collection<T> items) {
        this.items = items;
    }
    
    @Override
    public Iterator<T> iterator() {
        return items.iterator();
    }
    
    // 自定义流操作
    public Stream<T> parallelStream(int batchSize) {
        return StreamSupport.stream(
            Spliterators.spliteratorUnknownSize(
                iterator(), 
                Spliterator.IMMUTABLE | Spliterator.ORDERED
            ), 
            false
        );
    }
    
    // 分批次处理
    public void forEachBatch(int batchSize, Consumer<List<T>> batchConsumer) {
        List<T> batch = new ArrayList<>(batchSize);
        for (T item : this) {
            batch.add(item);
            if (batch.size() >= batchSize) {
                batchConsumer.accept(batch);
                batch.clear();
            }
        }
        if (!batch.isEmpty()) {
            batchConsumer.accept(batch);
        }
    }
}

七、高级迭代器模式

7.1 树形结构迭代器

java
java
下载
复制
// 二叉树迭代器
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    
    TreeNode(int val) { this.val = val; }
}

// 中序遍历迭代器
class InOrderIterator implements Iterator<TreeNode> {
    private final Deque<TreeNode> stack = new ArrayDeque<>();
    private TreeNode current;
    
    public InOrderIterator(TreeNode root) {
        this.current = root;
        pushLeft(current);
    }
    
    private void pushLeft(TreeNode node) {
        while (node != null) {
            stack.push(node);
            node = node.left;
        }
    }
    
    @Override
    public boolean hasNext() {
        return !stack.isEmpty();
    }
    
    @Override
    public TreeNode next() {
        if (!hasNext()) throw new NoSuchElementException();
        
        TreeNode node = stack.pop();
        pushLeft(node.right);
        return node;
    }
}

7.2 可关闭资源迭代器

java
java
下载
复制
// 带资源管理的迭代器
interface CloseableIterator<T> extends Iterator<T>, AutoCloseable {
    // 继承AutoCloseable,支持try-with-resources
}

class DatabaseIterator implements CloseableIterator<Map<String, Object>> {
    private Connection connection;
    private ResultSet resultSet;
    private boolean hasNext = false;
    
    public DatabaseIterator(String query) throws SQLException {
        connection = DriverManager.getConnection("jdbc:url");
        Statement stmt = connection.createStatement();
        resultSet = stmt.executeQuery(query);
        hasNext = resultSet.next();
    }
    
    @Override
    public boolean hasNext() {
        return hasNext;
    }
    
    @Override
    public Map<String, Object> next() {
        // 实现略
        return null;
    }
    
    @Override
    public void close() throws Exception {
        if (resultSet != null) resultSet.close();
        if (connection != null) connection.close();
    }
}

八、实际应用示例

8.1 Spring框架中的迭代器

java
java
下载
复制
// Spring Resource资源遍历
public class ResourceIteratorExample {
    public static void main(String[] args) throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resources = resolver.getResources("classpath*:/*.properties");
        
        // 使用迭代器模式处理资源
        for (Resource resource : resources) {
            System.out.println(resource.getFilename());
        }
    }
}

8.2 大数据分页迭代器

java
java
下载
复制
// 大数据分页查询迭代器
class PaginationIterator<T> implements Iterator<T> {
    private final int pageSize;
    private int currentPage = 0;
    private List<T> currentPageData = new ArrayList<>();
    private int indexInPage = 0;
    private final Supplier<List<T>> pageFetcher;
    
    public PaginationIterator(int pageSize, Supplier<List<T>> pageFetcher) {
        this.pageSize = pageSize;
        this.pageFetcher = pageFetcher;
        loadNextPage();
    }
    
    private void loadNextPage() {
        currentPageData = pageFetcher.get();
        indexInPage = 0;
        currentPage++;
    }
    
    @Override
    public boolean hasNext() {
        if (indexInPage < currentPageData.size()) {
            return true;
        }
        // 尝试加载下一页
        List<T> nextPage = pageFetcher.get();
        if (!nextPage.isEmpty()) {
            currentPageData = nextPage;
            indexInPage = 0;
            return true;
        }
        return false;
    }
    
    @Override
    public T next() {
        if (!hasNext()) throw new NoSuchElementException();
        return currentPageData.get(indexInPage++);
    }
}

九、与其他模式的关系

9.1 与组合模式结合

java
java
下载
复制
// 树形结构组合模式 + 迭代器
interface Component {
    String getName();
    Iterator<Component> createIterator();
}

class Composite implements Component {
    private String name;
    private List<Component> children = new ArrayList<>();
    
    public Composite(String name) { this.name = name; }
    
    public void add(Component component) {
        children.add(component);
    }
    
    @Override
    public String getName() { return name; }
    
    @Override
    public Iterator<Component> createIterator() {
        return new CompositeIterator(children.iterator());
    }
}

9.2 与访问者模式结合

java
java
下载
复制
// 迭代器 + 访问者模式
class VisitorIterator<T> {
    private final Iterator<T> iterator;
    
    public VisitorIterator(Iterator<T> iterator) {
        this.iterator = iterator;
    }
    
    public void accept(Visitor<T> visitor) {
        while (iterator.hasNext()) {
            visitor.visit(iterator.next());
        }
    }
}

总结

迭代器模式是最常用、最基础的设计模式之一,几乎所有的现代编程语言都内置了迭代器支持。Java从1.2版本引入集合框架时就包含了迭代器模式,后续的增强for循环、Stream API都是迭代器模式的演进。

关键实践要点

  1. 优先使用Java内置的IterableIterator接口
  2. 注意处理并发修改异常
  3. 大数据量时考虑懒加载和分页实现
  4. 资源密集型迭代器要实现AutoCloseable
  5. 考虑使用函数式编程简化迭代逻辑

迭代器模式体现了单一职责原则开闭原则的经典应用,是构建灵活、可扩展集合框架的基石。