迭代器模式:集合遍历的统一之道

摘要

迭代器模式(Iterator Pattern)是行为型设计模式中的"集合导航专家",它提供了一种方法顺序访问聚合对象中的各个元素,而又不暴露其内部表示。本文将深入剖析迭代器模式的核心概念、实现方式、应用场景及高级变体,通过丰富的Java代码示例展示如何构建灵活的集合遍历机制,并分析其与访问者模式、组合模式的区别与适用场景。

一、迭代器模式核心思想

迭代器模式的核心是分离集合遍历与集合实现,具有以下关键特征:

  1. 统一接口:为不同集合提供一致的遍历方式
  2. 内部封装:隐藏集合的内部数据结构
  3. 多态迭代:支持多种遍历策略
  4. 并行遍历:支持多个同时进行的遍历

适用场景:

  • 需要统一遍历不同结构的集合
  • 需要支持多种遍历方式
  • 需要隐藏集合的具体实现
  • 需要为集合提供统一的接口

二、迭代器模式结构解析

UML类图示意

[Aggregate] <|-- [ConcreteAggregate]
[Iterator] <|-- [ConcreteIterator]
[ConcreteAggregate] --> [ConcreteIterator]

核心组件角色

角色 职责 典型实现
Iterator 迭代器接口 定义遍历集合的方法
ConcreteIterator 具体迭代器 实现特定集合的迭代逻辑
Aggregate 聚合接口 定义创建迭代器的方法
ConcreteAggregate 具体聚合 实现集合数据结构及迭代器创建

三、基础实现:自定义集合迭代器

// 迭代器接口
interface Iterator<T> {boolean hasNext();T next();void remove();
}// 聚合接口
interface IterableCollection<T> {Iterator<T> createIterator();
}// 具体聚合:自定义列表
class CustomList<T> implements IterableCollection<T> {private List<T> items = new ArrayList<>();public void add(T item) {items.add(item);}public T get(int index) {return items.get(index);}public int size() {return items.size();}@Overridepublic Iterator<T> createIterator() {return new ListIterator<>(this);}// 具体迭代器private class ListIterator<T> implements Iterator<T> {private CustomList<T> list;private int index = 0;public ListIterator(CustomList<T> list) {this.list = list;}@Overridepublic boolean hasNext() {return index < list.size();}@Overridepublic T next() {if (!hasNext()) {throw new NoSuchElementException();}return list.get(index++);}@Overridepublic void remove() {if (index <= 0) {throw new IllegalStateException();}list.items.remove(--index);}}
}// 客户端使用
public class IteratorDemo {public static void main(String[] args) {CustomList<String> list = new CustomList<>();list.add("Apple");list.add("Banana");list.add("Cherry");Iterator<String> iterator = list.createIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

四、高级应用:树形结构迭代器

1. 二叉树迭代器

// 二叉树节点
class TreeNode<T> {T data;TreeNode<T> left;TreeNode<T> right;public TreeNode(T data) {this.data = data;}
}// 二叉树迭代器接口
interface TreeIterator<T> extends Iterator<T> {// 可添加树特有的遍历方法
}// 二叉树聚合
class BinaryTree<T> {private TreeNode<T> root;public void setRoot(TreeNode<T> root) {this.root = root;}public TreeIterator<T> createPreOrderIterator() {return new PreOrderIterator<>(root);}public TreeIterator<T> createInOrderIterator() {return new InOrderIterator<>(root);}public TreeIterator<T> createPostOrderIterator() {return new PostOrderIterator<>(root);}public TreeIterator<T> createLevelOrderIterator() {return new LevelOrderIterator<>(root);}
}// 前序遍历迭代器
class PreOrderIterator<T> implements TreeIterator<T> {private Stack<TreeNode<T>> stack = new Stack<>();public PreOrderIterator(TreeNode<T> root) {if (root != null) {stack.push(root);}}@Overridepublic boolean hasNext() {return !stack.isEmpty();}@Overridepublic T next() {if (!hasNext()) {throw new NoSuchElementException();}TreeNode<T> node = stack.pop();if (node.right != null) stack.push(node.right);if (node.left != null) stack.push(node.left);return node.data;}
}// 中序遍历迭代器
class InOrderIterator<T> implements TreeIterator<T> {private Stack<TreeNode<T>> stack = new Stack<>();private TreeNode<T> current;public InOrderIterator(TreeNode<T> root) {this.current = root;}@Overridepublic boolean hasNext() {return current != null || !stack.isEmpty();}@Overridepublic T next() {while (current != null) {stack.push(current);current = current.left;}TreeNode<T> node = stack.pop();current = node.right;return node.data;}
}// 使用示例
public class TreeIteratorDemo {public static void main(String[] args) {// 构建二叉树TreeNode<Integer> root = new TreeNode<>(1);root.left = new TreeNode<>(2);root.right = new TreeNode<>(3);root.left.left = new TreeNode<>(4);root.left.right = new TreeNode<>(5);BinaryTree<Integer> tree = new BinaryTree<>();tree.setRoot(root);// 前序遍历System.out.println("Pre-order traversal:");TreeIterator<Integer> preOrder = tree.createPreOrderIterator();while (preOrder.hasNext()) {System.out.print(preOrder.next() + " ");}// 中序遍历System.out.println("\nIn-order traversal:");TreeIterator<Integer> inOrder = tree.createInOrderIterator();while (inOrder.hasNext()) {System.out.print(inOrder.next() + " ");}}
}

2. 图遍历迭代器

// 图节点
class GraphNode<T> {T data;List<GraphNode<T>> neighbors = new ArrayList<>();public GraphNode(T data) {this.data = data;}public void addNeighbor(GraphNode<T> node) {neighbors.add(node);}
}// 图迭代器接口
interface GraphIterator<T> extends Iterator<T> {// 可添加图特有的遍历方法
}// 深度优先搜索迭代器
class DfsIterator<T> implements GraphIterator<T> {private Set<GraphNode<T>> visited = new HashSet<>();private Stack<GraphNode<T>> stack = new Stack<>();public DfsIterator(GraphNode<T> startNode) {if (startNode != null) {stack.push(startNode);visited.add(startNode);}}@Overridepublic boolean hasNext() {return !stack.isEmpty();}@Overridepublic T next() {if (!hasNext()) {throw new NoSuchElementException();}GraphNode<T> current = stack.pop();for (GraphNode<T> neighbor : current.neighbors) {if (!visited.contains(neighbor)) {stack.push(neighbor);visited.add(neighbor);}}return current.data;}
}// 广度优先搜索迭代器
class BfsIterator<T> implements GraphIterator<T> {private Set<GraphNode<T>> visited = new HashSet<>();private Queue<GraphNode<T>> queue = new LinkedList<>();public BfsIterator(GraphNode<T> startNode) {if (startNode != null) {queue.add(startNode);visited.add(startNode);}}@Overridepublic boolean hasNext() {return !queue.isEmpty();}@Overridepublic T next() {if (!hasNext()) {throw new NoSuchElementException();}GraphNode<T> current = queue.poll();for (GraphNode<T> neighbor : current.neighbors) {if (!visited.contains(neighbor)) {queue.add(neighbor);visited.add(neighbor);}}return current.data;}
}// 使用示例
public class GraphIteratorDemo {public static void main(String[] args) {// 构建图GraphNode<String> A = new GraphNode<>("A");GraphNode<String> B = new GraphNode<>("B");GraphNode<String> C = new GraphNode<>("C");GraphNode<String> D = new GraphNode<>("D");A.addNeighbor(B);A.addNeighbor(C);B.addNeighbor(D);C.addNeighbor(D);// DFS遍历System.out.println("DFS traversal:");GraphIterator<String> dfs = new DfsIterator<>(A);while (dfs.hasNext()) {System.out.print(dfs.next() + " ");}// BFS遍历System.out.println("\nBFS traversal:");GraphIterator<String> bfs = new BfsIterator<>(A);while (bfs.hasNext()) {System.out.print(bfs.next() + " ");}}
}

五、迭代器模式优缺点分析

优点:

优点 说明
单一职责 将遍历算法与集合分离
开闭原则 新增集合类型不影响现有代码
并行遍历 支持多个同时进行的遍历
统一接口 为不同集合提供一致遍历方式
封装性 隐藏集合内部实现细节

缺点:

缺点 说明
复杂度增加 简单集合使用迭代器可能过度设计
性能开销 间接访问可能带来轻微性能损失
修改限制 遍历过程中修改集合可能导致异常

六、迭代器模式与其他模式对比

迭代器模式 vs 访问者模式

维度 迭代器模式 访问者模式
目的 遍历集合元素 对元素执行操作
关注点 访问顺序 元素操作实现
元素耦合 元素类型无关 需要知道元素类型
扩展性 新增遍历方式容易 新增操作容易

迭代器模式 vs 组合模式

维度 迭代器模式 组合模式
目的 遍历集合元素 处理树形结构
关注点 元素访问顺序 部分-整体层次
结构 线性访问 递归结构
典型应用 集合遍历 UI组件、文件系统

七、迭代器模式最佳实践

1. 内部迭代器实现

// 内部迭代器接口
interface InternalIterator<T> {void forEach(Consumer<? super T> action);
}// 自定义集合实现内部迭代
class InternalList<T> implements InternalIterator<T> {private List<T> items = new ArrayList<>();public void add(T item) {items.add(item);}@Overridepublic void forEach(Consumer<? super T> action) {for (T item : items) {action.accept(item);}}
}// 使用示例
InternalList<String> names = new InternalList<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");names.forEach(System.out::println);

2. 过滤迭代器

// 过滤迭代器
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;advance();}private void advance() {hasNext = false;while (source.hasNext()) {nextItem = source.next();if (predicate.test(nextItem)) {hasNext = true;break;}}}@Overridepublic boolean hasNext() {return hasNext;}@Overridepublic T next() {if (!hasNext) {throw new NoSuchElementException();}T result = nextItem;advance();return result;}
}// 使用示例
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
Iterator<Integer> evenNumbers = new FilteringIterator<>(numbers.iterator(), n -> n % 2 == 0
);while (evenNumbers.hasNext()) {System.out.println(evenNumbers.next());
}

3. 线程安全迭代器

// 线程安全集合
class ConcurrentCollection<T> {private final List<T> items = new ArrayList<>();private final ReadWriteLock lock = new ReentrantReadWriteLock();public void add(T item) {lock.writeLock().lock();try {items.add(item);} finally {lock.writeLock().unlock();}}public Iterator<T> iterator() {return new ConcurrentIterator();}// 线程安全迭代器private class ConcurrentIterator implements Iterator<T> {private final List<T> snapshot;private int index = 0;public ConcurrentIterator() {lock.readLock().lock();try {this.snapshot = new ArrayList<>(items);} finally {lock.readLock().unlock();}}@Overridepublic boolean hasNext() {return index < snapshot.size();}@Overridepublic T next() {if (!hasNext()) {throw new NoSuchElementException();}return snapshot.get(index++);}}
}// 使用示例
ConcurrentCollection<String> safeCollection = new ConcurrentCollection<>();
safeCollection.add("Item1");
safeCollection.add("Item2");// 多线程环境下安全遍历
new Thread(() -> {Iterator<String> it = safeCollection.iterator();while (it.hasNext()) {System.out.println("Thread1: " + it.next());}
}).start();new Thread(() -> {safeCollection.add("Item3");Iterator<String> it = safeCollection.iterator();while (it.hasNext()) {System.out.println("Thread2: " + it.next());}
}).start();

八、迭代器模式在开源框架中的应用

Java集合框架

// List接口扩展了Iterable
public interface List<E> extends Collection<E>, Iterable<E> {Iterator<E> iterator();// 其他方法...
}// ArrayList的迭代器实现
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {public Iterator<E> iterator() {return new Itr();}private class Itr implements Iterator<E> {int cursor;       // 下一个元素的索引int lastRet = -1; // 上一个返回的元素的索引public boolean hasNext() {return cursor != size;}public E next() {checkForComodification();int i = cursor;if (i >= size)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i];}public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}
}

Spring Data的Repository

// Spring Data的查询方法返回Iterable
public interface UserRepository extends Repository<User, Long> {Iterable<User> findAllByActiveTrue();
}// 使用示例
@Autowired
private UserRepository userRepository;public void processActiveUsers() {Iterable<User> activeUsers = userRepository.findAllByActiveTrue();activeUsers.forEach(user -> {// 处理每个活跃用户});
}

九、高级应用:惰性求值迭代器

1. 数据库结果集迭代器

// 数据库结果集迭代器
class DatabaseResultIterator<T> implements Iterator<T> {private ResultSet resultSet;private RowMapper<T> rowMapper;private boolean hasNext;public DatabaseResultIterator(ResultSet resultSet, RowMapper<T> rowMapper) {this.resultSet = resultSet;this.rowMapper = rowMapper;this.hasNext = moveToNext();}private boolean moveToNext() {try {return resultSet.next();} catch (SQLException e) {throw new RuntimeException("Database access error", e);}}@Overridepublic boolean hasNext() {return hasNext;}@Overridepublic T next() {if (!hasNext) {throw new NoSuchElementException();}try {T item = rowMapper.mapRow(resultSet, resultSet.getRow());hasNext = moveToNext();return item;} catch (SQLException e) {throw new RuntimeException("Mapping failed", e);}}
}// 行映射器接口
interface RowMapper<T> {T mapRow(ResultSet rs, int rowNum) throws SQLException;
}// 使用示例
public List<User> findAllUsers(Connection conn) throws SQLException {Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM users");Iterator<User> iterator = new DatabaseResultIterator<>(rs, rs -> {User user = new User();user.setId(rs.getLong("id"));user.setName(rs.getString("name"));return user;});List<User> users = new ArrayList<>();iterator.forEachRemaining(users::add);return users;
}

2. 无限序列迭代器

// 斐波那契数列迭代器
class FibonacciIterator implements Iterator<BigInteger> {private BigInteger current = BigInteger.ZERO;private BigInteger next = BigInteger.ONE;@Overridepublic boolean hasNext() {return true; // 无限序列}@Overridepublic BigInteger next() {BigInteger result = current;current = next;next = result.add(current);return result;}
}// 使用示例(需要限制数量)
public class InfiniteSequenceDemo {public static void main(String[] args) {Iterator<BigInteger> fib = new FibonacciIterator();Stream.generate(() -> fib.next()).limit(20).forEach(System.out::println);}
}

十、迭代器模式未来发展趋势

新兴应用方向:

  1. 大数据处理:分布式集合的迭代器
  2. 响应式编程:异步数据流迭代
  3. 函数式编程:惰性求值迭代器
  4. AI数据处理:大规模训练数据集遍历
  5. 区块链:链上数据顺序访问

响应式迭代器

// Reactor中的Flux迭代器
Flux<Integer> flux = Flux.range(1, 10).map(i -> i * 2).filter(i -> i % 3 == 0);// 订阅处理相当于迭代
flux.subscribe(System.out::println,          // onNextThrowable::printStackTrace,   // onError() -> System.out.println("Completed") // onComplete
);// 或者转换为Iterable
Iterable<Integer> iterable = flux.toIterable();
for (Integer num : iterable) {System.out.println(num);
}

总结

迭代器模式是处理集合遍历的通用解决方案,它通过以下方式提升系统质量:

  1. 统一遍历接口:为不同集合提供一致的访问方式
  2. 解耦集合与算法:分离遍历逻辑与数据结构
  3. 并行遍历支持:允许多个同时进行的遍历
  4. 封装实现细节:隐藏集合的内部表示

现代应用关键点:

  • 函数式集成:结合Stream API和Lambda表达式
  • 惰性求值:实现高效的大数据集处理
  • 线程安全:设计并发环境下的安全迭代器
  • 资源管理:正确处理IO资源的关闭
  • 性能优化:避免不必要的对象创建

迭代器模式正在与函数式编程、响应式编程等现代范式结合,演进出更强大的数据处理能力。理解并掌握迭代器模式的精髓,将帮助开发者构建出更加灵活、高效的集合处理系统,特别是在大数据和分布式计算领域。