一、设计模式概述
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 实际应用场景
- 集合框架 - Java Collections Framework (ArrayList, HashSet等)
- 数据库访问 - 遍历查询结果集
- 文件系统 - 递归遍历目录结构
- 树结构遍历 - 二叉树、多叉树的前序/中序/后序遍历
- 图遍历 - BFS、DFS算法实现
- 分页查询 - 大数据量分页遍历
- 流式处理 - 大数据流处理
四、优缺点深度分析
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都是迭代器模式的演进。
关键实践要点:
- 优先使用Java内置的
Iterable和Iterator接口 - 注意处理并发修改异常
- 大数据量时考虑懒加载和分页实现
- 资源密集型迭代器要实现
AutoCloseable - 考虑使用函数式编程简化迭代逻辑
迭代器模式体现了单一职责原则 和开闭原则的经典应用,是构建灵活、可扩展集合框架的基石。