集合創建後,若需對每個元素進行統一操作(遍歷、過濾、轉換),不能依賴內部結構細節。Iterator 模式提供統一訪問接口,隱藏底層實現(數組、鏈表、樹等),實現「遍歷邏輯與數據結構解耦」。
public interface Iterator {
boolean hasNext(); // 是否還有下一個元素
E next(); // 返回下一個元素並移動指針
default void remove() { // 可選:從集合中移除當前元素
throw new UnsupportedOperationException();
}
default void forEachRemaining(Consumer super E> action) { ... }
}
所有 Collection 子類通過 iterator() 方法返回對應的 Iterator 實例。
List list = new ArrayList<>();
list.add("taoshihan1");
list.add("taoshihan2");
list.add("taoshihan3");
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
// 輸出:
// taoshihan1
// taoshihan2
// taoshihan3
注意:next() 必須在 hasNext() 返回 true 時調用,否則拋出 NoSuchElementException。
JDK 5+ 提供更簡潔的寫法,編譯器自動轉換為 Iterator 模式:
for (String s : list) {
System.out.println(s);
}
PHP 內建 foreach 支持數組與實現 Traversable 接口的對象。自定義迭代器需實現 Iterator 接口(5 個方法):
<?php
class MyIterator implements Iterator {
private $index = 0;
private $arr;
public function __construct(array $arr) { $this->arr = $arr; }
public function current() { return $this->arr[$this->index]; }
public function next() { ++$this->index; }
public function key() { return $this->index; }
public function valid() { return isset($this->arr[$this->index]); }
public function rewind() { $this->index = 0; }
}
$list = ["taoshihan1", "taoshihan2", "taoshihan3"];
$it = new MyIterator($list);
$it->rewind();
while ($it->valid()) {
echo $it->current() . "\n";
$it->next();
}
| 特性 | Java Iterator | PHP Iterator |
|---|---|---|
| 接口方法 | hasNext(), next(), remove() | current(), next(), key(), valid(), rewind() |
| 指針管理 | 內部封裝,調用 next() 前移 | 需手動 rewind() 重置,valid() 判斷有效性 |
| foreach 支持 | 語法糖,編譯期展開 | 原生語言結構,直接調用接口方法 |
| 移除元素 | remove() 默認拋異常,具體集合實現 | 無標準移除方法,需自行實現邏輯 |
forEach(Consumer)(JDK 8+),代碼更清晰。remove(),直接調用集合 remove() 會導致 ConcurrentModificationException。Iterable 與 Iterator 的關係:前者是「可迭代對象」工廠,後者是「迭代器」狀態持有者。