概念
迭代器设计模式
(Iterator Design Pattern)是一种行为型设计模式,它提供了一种方法来顺序访问一个聚合对象(如集合)的元素,而不需要暴露该对象的底层表示。迭代器模式可以帮助我们在不关心底层数据结构的情况下,遍历一个集合。
组成角色
- 抽象迭代器(Iterator):定义遍历元素所需的接口,通常包括 hasNext() 和 next() 方法。
- 具体迭代器(Concrete Iterator):实现抽象迭代器接口,完成对聚合对象的遍历。
- 抽象聚合(Aggregate):定义创建迭代器对象的接口,通常包括一个创建迭代器的方法。
- 具体聚合(Concrete Aggregate):实现抽象聚合接口,实例化具体迭代器。
相关图示
示例代码
import java.util.ArrayList;
import java.util.List;
// 抽象迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 具体迭代器
class ConcreteIterator implements Iterator {
private List<Object> list;
private int position = 0;
public ConcreteIterator(List<Object> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return position < list.size();
}
@Override
public Object next() {
return list.get(position++);
}
}
// 逆序具体迭代器
class ReverseConcreteIterator implements Iterator {
private List<Object> list;
private int position;
public ReverseConcreteIterator(List<Object> list) {
this.list = list;
position = list.size() - 1;
}
@Override
public boolean hasNext() {
return position >= 0;
}
@Override
public Object next() {
return list.get(position--);
}
}
// 抽象聚合接口
interface Aggregate {
Iterator createIterator(boolean reverse);
}
// 具体聚合
class ConcreteAggregate implements Aggregate {
private List<Object> list = new ArrayList<>();
public void addItem(Object item) {
list.add(item);
}
@Override
public Iterator createIterator(boolean reverse) {
return reverse ? new ReverseConcreteIterator(list) : new ConcreteIterator(list);
}
}
// 客户端代码
public class IteratorDemo {
public static void main(String[] args) {
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate.addItem("Item 1");
aggregate.addItem("Item 2");
aggregate.addItem("Item 3");
//顺序输出
Iterator iterator = aggregate.createIterator(false);
System.out.println("Normal order:");
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//逆序输出
Iterator reverseIterator = aggregate.createIterator(true);
System.out.println("\nReverse order:");
while (reverseIterator.hasNext()) {
System.out.println(reverseIterator.next());
}
}
}
框架中的运用
迭代器设计模式被广泛用于集合框架。集合框架包括一系列用于处理一组对象的接口和类,例如 List、Set 和 Map。迭代器设计模式使得遍历和操作这些集合变得简单和一致。
Java 集合框架中的迭代器设计模式主要涉及两个接口:java.util.Iterator
和 java.lang.Iterable
。
java.util.Iterator
:这是一个迭代器接口,定义了用于遍历集合元素的方法。主要方法有:boolean hasNext()
:如果仍有元素可以迭代,则返回 true。E next()
:返回迭代的下一个元素。void remove()
:从底层集合中移除迭代器返回的最后一个元素(可选操作)。
java.lang.Iterable
:这是一个表示可迭代对象的接口,通常由集合类实现。主要方法有:Iterator<E> iterator()
:返回一个迭代器,用于遍历集合元素。
ArrayList
是一个实现了 java.util.List
接口的可调整大小的数组。List
接口扩展了 java.util.Collection
,而 Collection
接口扩展了 java.lang.Iterable
。因此,ArrayList
类需要实现 Iterable
接口中的 iterator()
方法。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
// ...
// 实现 Iterable 接口中的 iterator() 方法
public Iterator<E> iterator() {
return new Itr();
}
// 内部类 Itr 实现了 Iterator 接口
private class Itr implements Iterator<E> {
int cursor; // 下一个元素的索引
int lastRet = -1; // 上一个元素的索引
// 实现 Iterator 接口中的 hasNext() 方法
public boolean hasNext() {
return cursor != size;
}
// 实现 Iterator 接口中的 next() 方法
@SuppressWarnings("unchecked")
public E next() {
// ...
Object[] elementData = ArrayList.this.elementData;
int i = cursor;
cursor = i + 1;
return (E) elementData[lastRet = i];
}
// 实现 Iterator 接口中的 remove() 方法
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
// ...
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
}
}
}
适用场景
- 不同的数据结构:当需要访问和遍历不同类型的数据结构(如数组、链表、树或图等)时,迭代器设计模式提供了一种统一的接口,使客户端代码能够以相同的方式处理这些不同的数据结构。
- 抽象数据访问:当需要对集合或容器中的元素进行访问,而不需要关心集合的具体实现细节时,迭代器设计模式可以提供一个抽象的访问接口,使得客户端代码可以处理元素而不依赖于容器的内部结构。
- 容器内部结构的封装:迭代器设计模式可以将容器的内部结构封装起来,使得容器的实现可以在不影响客户端代码的情况下进行修改。
- 支持多种遍历方式:当需要为集合提供多种遍历方式(例如正序遍历、逆序遍历、层次遍历等)时,可以为每种遍历方式实现一个具体的迭代器,这使得客户端代码可以方便地切换不同的遍历方式。