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

一、设计模式概述

1.1 核心思想

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

1.2 UML类图结构

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

二、完整Java代码实现

2.1 基本迭代器模式实现

csharp 复制代码
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 双向迭代器实现

csharp 复制代码
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集合框架中的迭代器

arduino 复制代码
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 泛型迭代器工厂

csharp 复制代码
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 文件系统遍历

arduino 复制代码
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 数据库查询结果遍历

typescript 复制代码
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 懒加载迭代器

ini 复制代码
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 可组合迭代器

csharp 复制代码
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 线程安全的迭代器

csharp 复制代码
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 支持过滤的迭代器

ini 复制代码
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 并发修改问题处理

csharp 复制代码
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 内存优化迭代器

csharp 复制代码
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集成

csharp 复制代码
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
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 可关闭资源迭代器

typescript 复制代码
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
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 大数据分页迭代器

csharp 复制代码
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 与组合模式结合

typescript 复制代码
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 与访问者模式结合

vbnet 复制代码
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. 考虑使用函数式编程简化迭代逻辑

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

相关推荐
数据中穿行2 小时前
观察者设计模式全方位深度解析
设计模式
程序员Terry2 小时前
别老写重复代码了!模版方法模式一次讲透
java·设计模式
数据中穿行2 小时前
建造者模式全方位深度解析
设计模式
数据中穿行2 小时前
组合设计模式全方位深度解析
设计模式
数据中穿行2 小时前
原型设计模式全方位深度解析
设计模式
CRMEB4 小时前
电商项目中订单流程可以使用哪些设计模式?如何开发?
java·设计模式·gitee·开源·php·crmeb
逆境不可逃5 小时前
【从零入门23种设计模式19】行为型之观察者模式
java·开发语言·算法·观察者模式·leetcode·设计模式·动态规划
天若有情6735 小时前
C++设计模式:tur函数——让对象自我裁决的条件选择器
java·c++·设计模式
犬小哈16 小时前
面试官:设计模式的 7 大基本原则有哪些?
设计模式