如何使用 Iterators

如何使用 Iterators

如果想要走訪一個集合,Kotlin 提供了一個機制 iterators (迭代物件)來循序存取每個元素,不需要暴露真實的底層結構,所以如果你想要處理每個元素,iterator 是一個很適合的工具。

說明

Iterator

無論 set 或者 list 都有提供內建的 iterator,一開始會指向集合的開頭,透過 next 會指向下一個元素,透過 hasNext() 方法可以得知是否還有下一個元素,這樣一來就可以走訪完整的集合,這樣是非常方便的,無論哪一種資料結構,只要是 set 或者 list 的相關子類別,只需要透過這樣統一的介面操作,就可以完成一個完整的走訪。

val numbers = listOf("one", "two", "three", "four")
val numbersIterator = numbers.iterator()
while (numbersIterator.hasNext()) {
    println(numbersIterator.next())
}

如果你用 for 迴圈也可以完成整個集合的走訪,因為它內建隱性的迭代物件。

val numbers = listOf("one", "two", "three", "four")
for (item in numbers) {
    println(item)
}

你點進去 in 看,會發現它包含著 iterator、hasNext 以及 next 物件。

你也可以透過集合內建的方法,foreach 方法來走訪所有的元素。

val numbers = listOf("one", "two", "three", "four")
numbers.forEach {
    println(it)
}

ListIterator

有一個特別的迭代器叫做 ListIterator, 它可以雙向走訪,也就是說除了向前走訪,也可以向後走訪,也可以透過 ListIterator 的 nextIndex 方法知道下一個元素的 index。

val numbers = listOf("one", "two", "three", "four")
val iterator = numbers.listIterator()
println("iterator.nextIndex():${iterator.nextIndex()}")

也可以透過 next 方法讓 iterator 指到下一個元素。

println("iterator.nextIndex():${iterator.nextIndex()}")
iterator.next()
println("iterator.nextIndex():${iterator.nextIndex()}")

結果如下。

iterator.nextIndex():0
iterator.nextIndex():1

你也可以透過 hasPrevious 知道是否有上一個元素。

val numbers = listOf("one", "two", "three", "four")
val iterator = numbers.listIterator()
println("iterator.hasPrevious():${iterator.hasPrevious()}") //false

如果已經是第一個元素了,使用 previous 方法,你將會得到一個驚喜。

Exception in thread "main" java.util.NoSuchElementException

MutableIterator

這是一個可變的 Iterator,代表你可以新增或者刪除任一元素,只要透過 next 前進時,在你想要的位置刪除元素即可。

val numbers = mutableListOf("one", "two", "three", "four") 
val mutableIterator = numbers.iterator()

mutableIterator.next()
mutableIterator.remove()    
println("After removal: $numbers")

結果如下。

After removal: [two, three, four]

如果你要新增元素就可以這樣做。

val numbers = mutableListOf("one", "four", "four")
val mutableListIterator = numbers.listIterator()

mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")
println(numbers)

結果如下。

[one, two, three, four]

參考資料

https://kotlinlang.org/docs/reference/iterators.html