提供一致的方式依序走訪一個聚合物件裡的元素,而不暴露它的內部結構。核心是把「怎麼走」從「裝什麼」中抽出來,讓陣列、樹、雜湊表都能用同一套
hasNext / next介面遍歷。
🧠 When to Use
TIP
訊號:你想讓外部「一個一個拿」集合裡的元素,但又不想(也不該)讓對方知道你底層是陣列、鏈結串列還是樹。
- 想隱藏聚合的內部表示,只暴露統一的遍歷介面。
- 同一個集合需要多種走訪方式(順序、反序、過濾)或多個遊標同時遍歷。
- 想讓走訪邏輯獨立於集合本身,各自演化、各自測試。
⚖️ Structure & Variants
經典版 — 實作語言內建 Iterator 介面
class Ring<T>(private val items: List<T>) : Iterable<T> {
override fun iterator() = object : Iterator<T> { // ← 外部 iterator
private var i = 0
override fun hasNext() = i < items.size
override fun next() = items[i++]
}
}
for (x in Ring(listOf("a", "b", "c"))) print(x) // abc- 實作
Iterable就能直接用for-in;呼叫端完全不知道底層是List。
外部 vs 內部 iterator
- 外部(external):呼叫端主動
hasNext()/next()控制節奏,能隨時暫停、跳出。 - 內部(internal):把元素一個個丟進你給的函數(如
forEach { }),遍歷節奏由集合掌控,寫起來簡潔但較難中途控制。
與語言內建 Sequence / lazy 的關係
- Kotlin 的
Sequence是惰性版迭代:map/filter串起來只在next()被拉時才逐元素計算,適合大量或無窮資料流。 - 多數情況直接用內建
Iterable/Sequence即可,很少需要手刻 GoF 那套類別。
⚠️ Misuse & Anti-patterns
- 重造輪子:現代語言都內建 iterator 協定,硬手刻一整套類別通常是過度工程。
- 遍歷途中修改集合:邊 iterate 邊 add/remove 常引發
ConcurrentModificationException或漏走元素。 - iterator 偷藏可變共享狀態:同一個 iterator 實例被多執行緒 / 多迴圈共用,遊標互相打架,結果不可預期。
🔑 Takeaways
- 本質是「統一遍歷介面、隱藏內部結構」,讓不同資料結構共用同一套走訪方式。
- 外部 iterator 可控、內部 iterator 簡潔;惰性需求交給
Sequence。 - 走訪 Composite 樹狀結構時常與它搭配;多半直接用語言內建,別重造輪子。
No notes yet — jot your takeaways or Q&A here.