迭代器模式提供一種方法順序訪問聚合對象元素,而無需暴露其內部表示。Java 集合框架完整實現了此模式。
// 聚合介面
public interface Collection {
void add(E e);
int size();
Iterator iterator(); // 工廠方法:創建迭代器
}
// 迭代器介面
public interface Iterator {
boolean hasNext(); // 是否有下一個
E next(); // 返回下一個並移動游標
// Java 8+ 默認方法
default void remove() { throw new UnsupportedOperationException(); }
default void forEachRemaining(Consumer super E> action) { ... }
}
public class MyArrayList implements Collection {
private static final int DEFAULT_CAPACITY = 10;
private Object[] elements;
private int size;
public MyArrayList() {
elements = new Object[DEFAULT_CAPACITY];
}
@Override
public void add(E e) {
ensureCapacity(size + 1);
elements[size++] = e;
}
private void ensureCapacity(int minCapacity) {
if (minCapacity > elements.length) {
int newCapacity = elements.length + (elements.length >> 1);
elements = Arrays.copyOf(elements, newCapacity);
}
}
@Override
public int size() { return size; }
@Override
public Iterator iterator() {
return new ArrayListIterator();
}
// 內部類實現迭代器(訪問外部類私有欄位)
private class ArrayListIterator implements Iterator {
private int cursor = 0; // 下一個元素索引
private int lastRet = -1; // 最後返回元素索引
@Override
public boolean hasNext() {
return cursor < size;
}
@Override
@SuppressWarnings("unchecked")
public E next() {
if (!hasNext()) throw new NoSuchElementException();
lastRet = cursor;
return (E) elements[cursor++];
}
@Override
public void remove() {
if (lastRet < 0) throw new IllegalStateException();
MyArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
}
}
// 內部刪除方法(供迭代器調用)
private E remove(int index) {
@SuppressWarnings("unchecked")
E old = (E) elements[index];
int numMoved = size - index - 1;
if (numMoved > 0) System.arraycopy(elements, index + 1, elements, index, numMoved);
elements[--size] = null;
return old;
}
}
public class IteratorPatternDemo {
public static void main(String[] args) {
Collection list = new MyArrayList<>();
for (int i = 0; i < 15; i++) {
list.add("元素" + i);
}
System.out.println("大小: " + list.size()); // 15
// 多態調用:介面類型持有具體實現
Iterator it = list.iterator();
while (it.hasNext()) {
String elem = it.next();
System.out.println(elem);
// 安全刪除示範
if (elem.equals("元素5")) {
it.remove();
System.out.println(">>> 已刪除: " + elem);
}
}
System.out.println("刪除後大小: " + list.size()); // 14
}
}
| 特性 | JDK 集合迭代器 | 自定義實現重點 |
|---|---|---|
| fail-fast | modCount 機制檢測結構修改 | 單線程環境可簡化或省略 |
| fail-safe | CopyOnWriteArrayList、ConcurrentHashMap | 複製底層數據、遍歷快照 |
| remove() | 支援、更新 modCount | 需同步更新集合 size/陣列 |
| forEachRemaining | 默認實現、可被重寫優化 | 簡單場景用默認即可 |