迭代器 是一種行為型設計模式,提供統一介面順序訪問聚合物件內部元素,而無需暴露其內部結構。Java 中 java.util.Iterator 是此模式的標準實現,被稱為「輕量級」物件,因建立開銷極小。
Iterator<E> 介面定義四個方法:
| 方法 | 回傳值 | 說明 |
|---|---|---|
hasNext() | boolean | 是否還有下一個元素 |
next() | E | 返回下一個元素並移動游標 |
remove() | void | 移除最後一次 next() 返回的元素(可選操作) |
forEachRemaining(Consumer) | void | Java 8+,對剩餘元素執行動作 |
List<String> list = new ArrayList<>(Arrays.asList("aa", "bb", "cc"));
// 方式一:for 迴圈
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
String s = it.next();
System.out.println(s);
}
// 方式二:while 迴圈
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
// 方式三:Java 8+ forEachRemaining
list.iterator().forEachRemaining(System.out::println);
唯一安全在迭代過程中修改集合的方式:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
if ("bb".equals(s)) {
it.remove(); // 僅能移除最後 next() 返回的元素
}
}
// 呼叫 list.remove() 會拋出 ConcurrentModificationException
專為 List 設計,繼承 Iterator 並新增:
hasPrevious()、previous()、nextIndex()、previousIndex()set(E e) 替換元素、add(E e) 插入元素ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
int idx = lit.nextIndex();
String val = lit.next();
if (idx == 1) {
lit.set("BB"); // 替換
lit.add("INSERT"); // 在當前位置前插入
}
}
集合內部維護 modCount 修改計數器。迭代器建立時捕獲 expectedModCount = modCount。每次 next()、remove() 先檢查:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
注意:此機制為「盡力而為」,不保證多執行緒下絕對安全,僅作為程式錯誤偵測輔助。
Java 8 引入 Spliterator,支援分割遍歷,是 Stream API 並行處理的基礎。特性旗標:
ORDERED、DISTINCT、SORTED、SIZED、NONNULL、IMMUTABLE、CONCURRENT、SUBSIZEDpublic class Range implements Iterable<Integer> {
private final int start, end;
public Range(int start, int end) { this.start = start; this.end = end; }
@Override
public Iterator<Integer> iterator() {
return new Iterator<>() {
int current = start;
public boolean hasNext() { return current < end; }
public Integer next() { return current++; }
};
}
}
// 使用:for (int i : new Range(0, 10)) { ... }
for (E e : coll)),編譯器自動轉為迭代器,碼簡潔且安全remove()Collections.synchronizedList、CopyOnWriteArrayList 或並行流Iterable 介面讓自定義類支援 for-each 語法