[Kotlin] Collection, Sequence - 1

Chloe Choi·2020년 12월 2일
0

Kotlin

목록 보기
2/11
post-thumbnail

Kotlin Standart Library는 많은 함수를 제공합니다. 이런 함수들은 다음 두 가지 방법을 통해 작업을 수행할 수 있습니다.

  • Eagerly with Collection
  • Lazily with Sequence

이 두 가지 컨테이너 타입에 대해 공부해볼게용

개념

Collection

  • Eagerly evaluated
  • 각 연산은 호출되었을 때 실행됨
  • 각 연산의 결과는 새로운 Collection에 저장됨 (== intermediate collection, 중간 컬렉션 결과값)

Sequence

  • Lazily evaluated
  • 두 가지 연산 타입을 가짐
    • intermediate operation
    • terminal operation
    • intermediate 연산은 terminal 연산이 호출될 때까지 실행되지 않고 저장되어 있음
    • 각 intermediate 연산은 각 element에 대해 발생
    • 정리하자면, Sequence는 각 item을 참조하지 않고 원본 items에 기반해 생성되며 수행해야하는 intermediate 연산들을 참조함

내부구현

위에서 본 차이점들 때문에 당연히 내부구현도 다르게 되어있겠죠? 간단히 살펴보겠습니다.

Collection

/**
 * Returns a list containing the results of applying the given [transform] function
 * to each element in the original collection.
 */
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
  • inline 함수를 사용함
  • 주석에서도 확인할 수 있듯, 연산이 적용된 새로운 ArrayList를 리턴함

Sequence

/**
 * Returns a sequence containing the results of applying the given [transform] function
 * to each element in the original sequence.
 *
 * The operation is _intermediate_ and _stateless_.
 */
public fun <T, R> Sequence<T>.map(transform: (T) -> R): Sequence<R> {
    return TransformingSequence(this, transform)
}
  • inline 함수를 사용하지 않음 (연산을 저장해야하는데 inline 함수는 저장할 수 없기 때문)
  • transform function이 새로운 Sequence 인스턴스에 저장되고 그게 리턴
  • (위와 같은 말인데 이해에 도움이 되는 문장입니당) decorates the previous one with the new operation
    +) 아래 코드에서 위 TransformingSequence에서 next()가 호출되었을 때, 다음 연산 또한 호출되도록 내부 구현이 되어있습니다. 또, 각 원소에 대해 독립적으로 실행되는 것도 확인할 수 있네요.
/**
 * A sequence which returns the results of applying the given [transformer] function to the values
 * in the underlying [sequence].
 */

internal class TransformingSequence<T, R>
constructor(private val sequence: Sequence<T>, private val transformer: (T) -> R) : Sequence<R> {
    override fun iterator(): Iterator<R> = object : Iterator<R> {
        val iterator = sequence.iterator()
        override fun next(): R {
            return transformer(iterator.next())
        }

        ...
    }

    ...
}

이번 글은 여기까지 적도록 하고 실제로 동작하는 방법, 그 동작으로 갖게 되는 Sequence의 장점 등은 다음 글에 마저 적도록 하겠습니다!

profile
똑딱똑딱

0개의 댓글