迭代器模式提供統一介面順序訪問聚合對象元素,不暴露內部結構 (數組、鏈表、樹、圖...)。核心角色:
hasNext()、next()、hasPrevious()、previous()。iterator() 工廠方法。iterator() 返回對應迭代器。
public interface ICollection {
IIterator iterator(); // 工廠方法
void add(T item);
T get(int index);
int size();
}
public interface IIterator {
boolean hasNext();
boolean hasPrevious();
T next();
T previous();
}
public class MyArrayList implements ICollection {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_CAPACITY = 10;
public MyArrayList() { elements = new Object[DEFAULT_CAPACITY]; }
@Override
public void add(T item) {
ensureCapacity();
elements[size++] = item;
}
@Override
public T get(int index) { checkIndex(index); return (T) elements[index]; }
@Override
public int size() { return size; }
@Override
public IIterator iterator() {
return new ArrayIterator<>(this);
}
private void ensureCapacity() {
if (size == elements.length) {
elements = Arrays.copyOf(elements, size * 2);
}
}
private void checkIndex(int i) { if (i < 0 || i >= size) throw new IndexOutOfBoundsException(); }
// 內部類訪問私有字段
private static class ArrayIterator implements IIterator {
private final MyArrayList list;
private int cursor = 0;
ArrayIterator(MyArrayList list) { this.list = list; }
public boolean hasNext() { return cursor < list.size; }
public boolean hasPrevious() { return cursor > 0; }
public T next() { if (!hasNext()) throw new NoSuchElementException(); return list.get(cursor++); }
public T previous() { if (!hasPrevious()) throw new NoSuchElementException(); return list.get(--cursor); }
}
}
public class MyLinkedList implements ICollection {
private Node head, tail;
private int size = 0;
static class Node { T item; Node next, prev; }
public void add(T item) {
Node node = new Node<>(); node.item = item;
if (tail == null) head = tail = node;
else { tail.next = node; node.prev = tail; tail = node; }
size++;
}
@Override public T get(int index) { /* 遍歷查找略 */ return null; }
@Override public int size() { return size; }
@Override
public IIterator iterator() {
return new LinkedIterator<>(this);
}
private static class LinkedIterator implements IIterator {
private final MyLinkedList list;
private Node current = list.head;
LinkedIterator(MyLinkedList list) { this.list = list; }
public boolean hasNext() { return current != null; }
public boolean hasPrevious() { return current != list.head; }
public T next() { if (!hasNext()) throw new NoSuchElementException(); T item = current.item; current = current.next; return item; }
public T previous() { if (!hasPrevious()) throw new NoSuchElementException(); current = current.prev; return current.item; }
}
}
public class IteratorDemo {
public static void main(String[] args) {
// 測試動態數組
ICollection arrayColl = new MyArrayList<>();
arrayColl.add("A"); arrayColl.add("B"); arrayColl.add("C");
traverse(arrayColl);
// 測試鏈表
ICollection linkedColl = new MyLinkedList<>();
linkedColl.add(1); linkedColl.add(2); linkedColl.add(3);
traverse(linkedColl);
}
static void traverse(ICollection coll) {
System.out.println("=== 遍歷 " + coll.getClass().getSimpleName() + " ===");
for (IIterator it = coll.iterator(); it.hasNext(); ) {
System.out.print(it.next() + " ");
}
System.out.println("\n=== 反向遍歷 ===");
for (IIterator it = coll.iterator(); it.hasPrevious(); ) {
System.out.print(it.previous() + " ");
}
System.out.println("\n");
}
}
=== 遍歷 MyArrayList === A B C === 反向遍歷 === C B A === 遍歷 MyLinkedList === 1 2 3 === 反向遍歷 === 3 2 1
Collection.iterator() 返回 Iterator — 標準角色映射。List.listIterator() 返回 ListIterator — 增強版 (雙向、索引、修改)。Map 無直接迭代器,但 entrySet()、keySet()、values() 返回可迭代視圖。
// Iterable 繼承自 Iterable,支援 forEach
coll.forEach(System.out::print); // 內部迭代
// Stream API (內部迭代、並行、管道)
coll.stream().filter(s -> s.length() > 1).map(String::toUpperCase).forEach(System.out::println);
| 模式 | 核心意圖 | 關鍵差異 |
|---|---|---|
| 迭代器 | 統一遍歷介面 | 關注「如何遍歷」,封裝遍歷狀態 |
| 訪問者 | 分離操作與對象結構 | 關注「做什麼操作」,雙分發 |
| 組合 | 樹形結構統一介面 | 關注「部分-整體」層次 |