반복자

반복자 (Iterators)

컬렉션 요소를 순회할 때, Kotlin 표준 라이브러리는 널리 쓰이는 반복자(iterator) 메커니즘을 지원합니다. 반복자는 컬렉션의 내부 구조를 드러내지 않으면서 요소들에 순차적으로 접근할 수 있게 해주는 객체예요. 컬렉션의 모든 요소를 하나씩 처리해야 할 때 — 예를 들어 값을 출력하거나 비슷한 갱신을 해야 할 때 — 반복자가 유용합니다.

반복자는 Iterable<T> 인터페이스의 하위 타입들(SetList 포함)에서 iterator() 함수를 호출해 얻을 수 있어요.

반복자를 얻으면 그것은 컬렉션의 첫 번째 요소를 가리킵니다. next() 함수를 호출하면 이 요소를 반환하고, 다음 요소가 있다면 반복자 위치를 그 다음 요소로 옮겨요.

반복자가 마지막 요소를 지나고 나면, 더 이상 요소를 꺼내는 데 사용할 수 없고 이전 위치로 되돌릴 수도 없습니다. 컬렉션을 다시 순회하려면 새 반복자를 만들어야 해요.

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

Iterable 컬렉션을 순회하는 또 다른 방법은 잘 알려진 for 루프예요. 컬렉션에 for를 쓰면 반복자를 암시적으로 얻습니다. 그래서 다음 코드는 위 예시와 동등해요.

fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four")
    for (item in numbers) {
        println(item)
        // one
        // two
        // three
        // four
    }
//sampleEnd
}

마지막으로 유용한 forEach() 함수가 있는데, 컬렉션을 자동으로 순회하며 각 요소에 대해 주어진 코드를 실행합니다. 같은 예시를 이렇게 쓸 수 있어요.

fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four")
    numbers.forEach {
        println(it)
        // one
        // two
        // three
        // four
    }
//sampleEnd
}

출처: Kotlin 공식 문서

본문

리스트 반복자

리스트에는 특별한 반복자 구현인 ListIterator가 있어요. 리스트를 앞뒤 양방향으로 순회하는 것을 지원합니다.

뒤로 순회하는 것은 hasPrevious()previous() 함수로 구현돼요. 추가로 ListIteratornextIndex()previousIndex() 함수로 요소 인덱스에 대한 정보도 제공합니다.

fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four")
    val listIterator = numbers.listIterator()
    while (listIterator.hasNext()) listIterator.next()
    println("Iterating backwards:")
    // Iterating backwards:
    while (listIterator.hasPrevious()) {
        print("Index: ${listIterator.previousIndex()}")
        println(", value: ${listIterator.previous()}")
        // Index: 3, value: four
        // Index: 2, value: three
        // Index: 1, value: two
        // Index: 0, value: one
    }
//sampleEnd
}

양방향으로 순회할 수 있다는 것은, ListIterator가 마지막 요소에 도달한 뒤에도 계속 사용할 수 있다는 뜻이에요.

변경 가능한 반복자

변경 가능한(mutable) 컬렉션을 순회할 때는 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")
    // After removal: [two, three, four]
//sampleEnd
}

요소를 제거하는 것 외에도, MutableListIterator는 리스트를 순회하면서 add()set() 함수로 요소를 삽입·대체할 수 있어요.

fun main() {
//sampleStart
    val numbers = mutableListOf("one", "four", "four")
    val mutableListIterator = numbers.listIterator()

    mutableListIterator.next()
    mutableListIterator.add("two")
    println(numbers)
    // [one, two, four, four]
    mutableListIterator.next()
    mutableListIterator.set("three")
    println(numbers)
    // [one, two, three, four]
//sampleEnd
}

더 알아보기 (Learn more)