Итераторы
Для обхода элементов коллекции стандартная библиотека Kotlin поддерживает широко используемый механизм итераторов – объектов, предоставляющих последовательный доступ к элементам без раскрытия внутренней структуры коллекции. Итераторы полезны, когда вам нужно обработать все элементы коллекции по одному, например, вывести значения или выполнить аналогичные обновления.
Итераторы можно получить для наследников интерфейса Iterable<T>, включая Set и List, вызвав функцию iterator().
После получения итератора он указывает на первый элемент коллекции; вызов функции next() возвращает этот элемент и перемещает позицию итератора к следующему элементу, если он существует.
После того как итератор пройдёт через последний элемент, он больше не может использоваться для извлечения элементов; также его нельзя переместить в предыдущую позицию. Чтобы снова пройти по коллекции, создайте новый итератор.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val numbersIterator = numbers.iterator()
while (numbersIterator.hasNext()) {
println(numbersIterator.next())
}
//sampleEnd
}
Другой способ пройти по коллекции Iterable — это хорошо известный цикл for. При использовании for с коллекцией итератор получается неявно. Таким образом, следующий код эквивалентен приведенному выше примеру:
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
for (item in numbers) {
println(item)
}
//sampleEnd
}
Наконец, есть полезная функция forEach(), которая позволяет автоматически пройти по коллекции и выполнить заданный код для каждого элемента. Следующий пример будет выглядеть так:
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
numbers.forEach {
println(it)
}
//sampleEnd
}
Итераторы списков
Для списков существует специальная реализация итератора: ListIterator. Он поддерживает итерацию списков в обоих направлениях: вперёд и назад.
Обратная итерация реализована функциями hasPrevious() и previous(). Кроме того, ListIterator предоставляет информацию об индексах элементов с помощью функций nextIndex() и previousIndex().
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val listIterator = numbers.listIterator()
while (listIterator.hasNext()) listIterator.next()
println("Iterating backwards:")
while (listIterator.hasPrevious()) {
print("Index: ${listIterator.previousIndex()}")
println(", value: ${listIterator.previous()}")
}
//sampleEnd
}
Возможность итерации в обоих направлениях означает, что ListIterator по-прежнему может быть использован после достижения последнего элемента.
Изменяемые итераторы
Для итерации по изменяемым коллекциям существует MutableIterator, который расширяет Iterator функцией удаления элементов remove(). Таким образом, вы можете удалять элементы из коллекции во время итерации.
fun main() {
//sampleStart
val numbers = mutableListOf("one", "two", "three", "four")
val mutableIterator = numbers.iterator()
mutableIterator.next()
mutableIterator.remove()
println("After removal: $numbers")
//sampleEnd
}
Помимо удаления элементов, MutableListIterator также может вставлять и заменять элементы во время итерации по списку.
fun main() {
//sampleStart
val numbers = mutableListOf("one", "four", "four")
val mutableListIterator = numbers.listIterator()
mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")
println(numbers)
//sampleEnd
}
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/iterators.html