Java迭代器模式详解

迭代器模式详解

一、迭代器模式概述

迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。迭代器模式将遍历逻辑从聚合对象中分离出来,使得聚合对象和遍历算法可以独立变化。

核心特点

  • 统一遍历接口:提供一致的遍历方式
  • 解耦集合与遍历:集合结构变化不影响遍历代码
  • 支持多种遍历:可定义不同的迭代策略
  • 简化集合接口:集合只需提供创建迭代器的方法

二、迭代器模式的结构

主要角色

  1. Iterator:迭代器接口,定义访问和遍历元素的接口
  2. ConcreteIterator:具体迭代器,实现迭代器接口
  3. Aggregate:聚合接口,定义创建迭代器的方法
  4. ConcreteAggregate:具体聚合,实现创建迭代器的方法

三、迭代器模式的实现

1. 基本实现

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

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

// 具体聚合 - 数组集合
public class ArrayCollection<T> implements Aggregate<T> {
    private T[] items;
    
    public ArrayCollection(T[] items) {
        this.items = items;
    }
    
    public Iterator<T> createIterator() {
        return new ArrayIterator<T>(items);
    }
}

// 具体迭代器 - 数组迭代器
public class ArrayIterator<T> implements Iterator<T> {
    private T[] items;
    private int position = 0;
    
    public ArrayIterator(T[] items) {
        this.items = items;
    }
    
    public boolean hasNext() {
        return position < items.length;
    }
    
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        return items[position++];
    }
}

// 使用示例
String[] names = {"Alice", "Bob", "Charlie"};
Aggregate<String> collection = new ArrayCollection<>(names);
Iterator<String> iterator = collection.createIterator();

while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

2. 支持双向遍历的迭代器

// 扩展的迭代器接口
public interface BidirectionalIterator<T> extends Iterator<T> {
    boolean hasPrevious();
    T previous();
    void reset();
}

// 双向数组迭代器
public class BidirectionalArrayIterator<T> implements BidirectionalIterator<T> {
    private T[] items;
    private int position = 0;
    
    public BidirectionalArrayIterator(T[] items) {
        this.items = items;
    }
    
    public boolean hasNext() {
        return position < items.length;
    }
    
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        return items[position++];
    }
    
    public boolean hasPrevious() {
        return position > 0;
    }
    
    public T previous() {
        if (!hasPrevious()) {
            throw new NoSuchElementException();
        }
        return items[--position];
    }
    
    public void reset() {
        position = 0;
    }
}

四、迭代器模式的应用场景

1. 自定义集合遍历

// 树节点
public class TreeNode<T> {
    private T value;
    private List<TreeNode<T>> children = new ArrayList<>();
    
    public TreeNode(T value) {
        this.value = value;
    }
    
    public void addChild(TreeNode<T> child) {
        children.add(child);
    }
    
    // 创建深度优先迭代器
    public Iterator<T> createDepthFirstIterator() {
        return new DepthFirstIterator<>(this);
    }
    
    // 创建广度优先迭代器
    public Iterator<T> createBreadthFirstIterator() {
        return new BreadthFirstIterator<>(this);
    }
}

// 深度优先迭代器
public class DepthFirstIterator<T> implements Iterator<T> {
    private Stack<TreeNode<T>> stack = new Stack<>();
    
    public DepthFirstIterator(TreeNode<T> root) {
        stack.push(root);
    }
    
    public boolean hasNext() {
        return !stack.isEmpty();
    }
    
    public T next() {
        TreeNode<T> node = stack.pop();
        for (int i = node.children.size() - 1; i >= 0; i--) {
            stack.push(node.children.get(i));
        }
        return node.value;
    }
}

2. 文件系统遍历

// 文件系统条目接口
public interface FileSystemItem {
    String getName();
    Iterator<FileSystemItem> createIterator();
}

// 文件类
public class File implements FileSystemItem {
    private String name;
    
    public File(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public Iterator<FileSystemItem> createIterator() {
        return Collections.emptyIterator();
    }
}

// 目录类
public class Directory implements FileSystemItem {
    private String name;
    private List<FileSystemItem> items = new ArrayList<>();
    
    public Directory(String name) {
        this.name = name;
    }
    
    public void addItem(FileSystemItem item) {
        items.add(item);
    }
    
    public String getName() {
        return name;
    }
    
    public Iterator<FileSystemItem> createIterator() {
        return new DirectoryIterator(items);
    }
}

// 目录迭代器
public class DirectoryIterator implements Iterator<FileSystemItem> {
    private Stack<Iterator<FileSystemItem>> stack = new Stack<>();
    
    public DirectoryIterator(List<FileSystemItem> items) {
        stack.push(items.iterator());
    }
    
    public boolean hasNext() {
        if (stack.isEmpty()) return false;
        
        Iterator<FileSystemItem> iterator = stack.peek();
        if (iterator.hasNext()) {
            return true;
        } else {
            stack.pop();
            return hasNext();
        }
    }
    
    public FileSystemItem next() {
        Iterator<FileSystemItem> iterator = stack.peek();
        FileSystemItem item = iterator.next();
        
        if (item instanceof Directory) {
            stack.push(item.createIterator());
        }
        
        return item;
    }
}

3. 数据库结果集遍历

// 数据库结果集接口
public interface ResultSet<T> {
    Iterator<T> iterator();
}

// 分页结果集实现
public class PagedResultSet<T> implements ResultSet<T> {
    private PageFetcher<T> fetcher;
    private int pageSize;
    
    public PagedResultSet(PageFetcher<T> fetcher, int pageSize) {
        this.fetcher = fetcher;
        this.pageSize = pageSize;
    }
    
    public Iterator<T> iterator() {
        return new PagedIterator<>(fetcher, pageSize);
    }
}

// 分页迭代器
public class PagedIterator<T> implements Iterator<T> {
    private PageFetcher<T> fetcher;
    private int pageSize;
    private List<T> currentPage;
    private int currentIndex;
    private int currentPageNumber;
    
    public PagedIterator(PageFetcher<T> fetcher, int pageSize) {
        this.fetcher = fetcher;
        this.pageSize = pageSize;
        this.currentPageNumber = 0;
        loadNextPage();
    }
    
    public boolean hasNext() {
        if (currentIndex < currentPage.size()) {
            return true;
        }
        return currentPage.size() == pageSize; // 如果不满一页,说明没有下一页
    }
    
    public T next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        
        if (currentIndex >= currentPage.size()) {
            loadNextPage();
            currentIndex = 0;
        }
        
        return currentPage.get(currentIndex++);
    }
    
    private void loadNextPage() {
        currentPage = fetcher.fetchPage(currentPageNumber++, pageSize);
        currentIndex = 0;
    }
}

五、迭代器模式的变体

1. 内部类迭代器

public class BookCollection implements Iterable<Book> {
    private List<Book> books = new ArrayList<>();
    
    public void addBook(Book book) {
        books.add(book);
    }
    
    public Iterator<Book> iterator() {
        return new BookIterator();
    }
    
    // 内部类实现迭代器
    private class BookIterator implements Iterator<Book> {
        private int currentIndex = 0;
        
        public boolean hasNext() {
            return currentIndex < books.size();
        }
        
        public Book next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            return books.get(currentIndex++);
        }
    }
}

2. 过滤迭代器

public class FilteringIterator<T> implements Iterator<T> {
    private Iterator<T> source;
    private Predicate<T> predicate;
    private T nextItem;
    private boolean hasNext;
    
    public FilteringIterator(Iterator<T> source, Predicate<T> predicate) {
        this.source = source;
        this.predicate = predicate;
        findNext();
    }
    
    public boolean hasNext() {
        return hasNext;
    }
    
    public T next() {
        if (!hasNext) {
            throw new NoSuchElementException();
        }
        T result = nextItem;
        findNext();
        return result;
    }
    
    private void findNext() {
        hasNext = false;
        while (source.hasNext()) {
            nextItem = source.next();
            if (predicate.test(nextItem)) {
                hasNext = true;
                break;
            }
        }
    }
}

六、迭代器模式的优缺点

优点

  1. 单一职责原则:将遍历算法与集合分离
  2. 开闭原则:可以新增迭代器而不修改集合
  3. 并行遍历:可同时使用多个迭代器遍历同一集合
  4. 延迟加载:可按需获取元素,节省内存

缺点

  1. 简单集合可能过度设计:对简单集合使用迭代器可能增加复杂度
  2. 效率可能降低:某些情况下比直接遍历效率低
  3. 实现复杂:某些复杂数据结构的迭代器实现较困难

七、最佳实践

  1. 优先实现Iterable接口:使集合支持for-each循环
  2. 考虑线程安全:多线程环境下的迭代器安全性
  3. 支持快速失败:迭代过程中检测集合修改
  4. 资源清理:实现Closeable接口释放资源
  5. 组合使用:与过滤器、映射器等组合使用

八、总结

迭代器模式是集合遍历的标准解决方案,特别适用于:

  • 需要统一遍历不同结构的集合
  • 需要支持多种遍历方式
  • 需要隐藏集合内部实现
  • 需要延迟加载或分批处理数据

在实际开发中,迭代器模式常见于:

  • Java集合框架(Collection.iterator())
  • 数据库结果集遍历
  • 树形结构遍历
  • 文件系统遍历
  • 分页数据加载

正确使用迭代器模式可以提高代码的复用性和灵活性,但对于简单遍历需求,直接使用for循环可能更简洁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值