迭代器模式(Iterator Pattern)
概念
迭代器模式是一种行为型设计模式,它用于提供一种顺序访问聚合对象(如集合、列表、数组)元素的方式,而无需暴露该对象的内部表示。迭代器模式将遍历行为从集合对象中分离出来,通过提供统一的接口来访问不同聚合对象中的元素。
应用场景
-
遍历集合对象:在系统中需要遍历不同类型的集合(如列表、栈、队列)时,迭代器模式可以提供一致的方式来遍历,而不必了解集合的内部结构。
-
封装集合的内部结构:迭代器隐藏了集合的具体实现细节,用户不需要关心集合的内部实现,例如数组的长度、链表的节点等,避免了直接操作集合对象。
-
解耦集合与算法:通过将遍历算法与集合本身分离,用户可以独立定义不同的迭代器,满足特定的遍历需求,如正序遍历、倒序遍历、跳步遍历等。
注意点
-
并发修改问题:当集合在遍历过程中被修改(如新增或删除元素),可能会引发并发修改异常,需要特别注意在多线程场景下的使用。
-
迭代器失效问题:一些容器在迭代时,如果容器内部结构改变(比如删除了一个元素),默认的迭代器会失效并抛出异常。
-
内存管理:如果集合特别大且占用大量内存,使用迭代器遍历时应考虑如何管理内存,例如在遍历过程中是否需要保持所有元素在内存中。
核心要素
-
Iterator(迭代器接口) :定义访问和遍历元素的方法,例如
next()
和hasNext()
。 -
ConcreteIterator(具体迭代器):具体的迭代器实现,实现迭代器接口并维护遍历状态。
-
Aggregate(聚合对象接口):定义创建迭代器的接口,用于返回具体的迭代器对象。
-
ConcreteAggregate(具体聚合对象):具体的集合类,实现创建迭代器的接口,并负责存储对象。
Java代码完整示例
代码示例:简单的迭代器模式实现
java
import java.util.ArrayList;
import java.util.List;
// 迭代器接口
interface Iterator<T> {
boolean hasNext();
T next();
}
// 聚合对象接口
interface Aggregate<T> {
Iterator<T> createIterator();
}
// 具体迭代器实现
class ConcreteIterator<T> implements Iterator<T> {
private List<T> items;
private int position = 0;
public ConcreteIterator(List<T> items) {
this.items = items;
}
@Override
public boolean hasNext() {
return position < items.size();
}
@Override
public T next() {
return items.get(position++);
}
}
// 具体聚合对象实现
class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> items = new ArrayList<>();
public void addItem(T item) {
items.add(item);
}
@Override
public Iterator<T> createIterator() {
return new ConcreteIterator<>(items);
}
}
// 客户端代码
public class IteratorPatternDemo {
public static void main(String[] args) {
ConcreteAggregate<String> aggregate = new ConcreteAggregate<>();
aggregate.addItem("Item 1");
aggregate.addItem("Item 2");
aggregate.addItem("Item 3");
Iterator<String> iterator = aggregate.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
输出结果:
Item 1
Item 2
Item 3
各种变形用法完整示例
-
倒序迭代器
有时需要反向遍历集合,这时可以通过实现倒序迭代器来实现。
代码示例:倒序迭代器
javaclass ReverseIterator<T> implements Iterator<T> { private List<T> items; private int position; public ReverseIterator(List<T> items) { this.items = items; this.position = items.size() - 1; } @Override public boolean hasNext() { return position >= 0; } @Override public T next() { return items.get(position--); } } public class ReverseIteratorPatternDemo { public static void main(String[] args) { ConcreteAggregate<String> aggregate = new ConcreteAggregate<>(); aggregate.addItem("Item 1"); aggregate.addItem("Item 2"); aggregate.addItem("Item 3"); Iterator<String> reverseIterator = new ReverseIterator<>(aggregate.createIterator().items); while (reverseIterator.hasNext()) { System.out.println(reverseIterator.next()); } } }
输出结果:
Item 3 Item 2 Item 1
-
迭代器失效和并发修改异常
当集合在迭代过程中发生变化时,通常会抛出
ConcurrentModificationException
异常,尤其在使用Java自带的集合类时需要特别注意。代码示例:并发修改异常
javaimport java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ConcurrentModificationDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Item 1"); list.add("Item 2"); list.add("Item 3"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); System.out.println(item); // 在迭代过程中修改集合,抛出异常 if ("Item 2".equals(item)) { list.remove(item); } } } }
输出结果:
Item 1 Item 2 Exception in thread "main" java.util.ConcurrentModificationException
-
自定义迭代器与泛型支持
迭代器模式可以通过泛型来实现对不同类型的集合进行遍历。
代码示例:自定义泛型迭代器
javaclass GenericAggregate<T> implements Aggregate<T> { private List<T> items = new ArrayList<>(); public void addItem(T item) { items.add(item); } @Override public Iterator<T> createIterator() { return new ConcreteIterator<>(items); } } public class GenericIteratorPatternDemo { public static void main(String[] args) { GenericAggregate<Integer> intAggregate = new GenericAggregate<>(); intAggregate.addItem(1); intAggregate.addItem(2); intAggregate.addItem(3); Iterator<Integer> intIterator = intAggregate.createIterator(); while (intIterator.hasNext()) { System.out.println(intIterator.next()); } GenericAggregate<String> stringAggregate = new GenericAggregate<>(); stringAggregate.addItem("Item A"); stringAggregate.addItem("Item B"); Iterator<String> stringIterator = stringAggregate.createIterator(); while (stringIterator.hasNext()) { System.out.println(stringIterator.next()); } } }
输出结果:
1 2 3 Item A Item B
-
内部类实现迭代器
Java标准库中的集合类,如
ArrayList
等,通常通过内部类实现自己的迭代器。代码示例:内部类实现迭代器
javaclass MyCollection<T> { private List<T> items = new ArrayList<>(); public void addItem(T item) { items.add(item); } public Iterator<T> iterator() { return new MyIterator(); } private class MyIterator implements Iterator<T> { private int index = 0; @Override public boolean hasNext() { return index < items.size(); } @Override public T next() { return items.get(index++); } } } public class InnerClassIteratorDemo { public static void main(String[] args) { MyCollection<String> collection = new MyCollection<>(); collection.addItem("Item X"); collection.addItem("Item Y"); Iterator<String> iterator = collection.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
输出结果:
Item X Item Y
总结
迭代器模式通过提供统一的遍历接口,隐藏了聚合对象的内部结构,使得代码能够适应多种不同的集合类型。在实际开发中,Java标准库已经内置了大量的迭代器实现(如List
、Set
等),我们可以直接使用或扩展这些实现,来满足不同的需求。