본문 바로가기
👨‍💻 프로그래밍/Java, Kotlin, Spring

Kotlin Sequence (스퀸스) 에 대해 알아보자

by 개발자 진개미 2024. 2. 4.
반응형


🐜 Sequence, 본질적으로 뭘까?

Type

 

Kotlin의 SequenceType입니다. Collection 처럼 값을 담고 있지만 Eager하게 만드는게 아닌 Lazy하게 만들어 대량의 데이터를 효율적으로 다루거나 무한히 계속되는 데이터를 다룰 수 있게 해 줍니다.

예를들어 아래와 같이 특정 연산을 하고 난 결과의 1번째 값을 가져오는 코드가 있다고 해 봅시다.

(100 until 2_000_000)
	.map { it * 2 }
	.filter { it % 3 == 0 }
	.first()

 

이 코드의 내부 동작을 살펴보면 우선 map으로 모든 원소를 2배 한 후, filter로 모든 원소의 나머지를 계산해 0인 원소만 남긴 뒤, 여기서 첫 번째 원소를 가져옵니다. Eager 하게 동작하기 때문에 이런식으로 코드를 짜면 1번째 원소만 있으면 되는데 끝까지 모두 계산하게 됩니다.

하지만 아래와 같이 똑같은 코드를 Sequence를 이용해 짜면 Lazy하게 동작하기 때문에 1번째 원소에 모든 연산을 하고, 2번째 원소에 모든 연산을 하고 ... 조건이 맞으면 연산도 끝나게 됩니다.

(100 until 2_000_000)
	.asSequnece()
	.map { it * 2 }
	.filter { it % 3 == 0 }
	.first()

🐜 Sequence를 만드는 법

Sequnece는 크게 3가지 방법으로 만들 수 있습니다.

1. sequenceOf()

arrayOf, mapOf 처럼 미리 sequence를 이룰 값을 알고 있으면 sequenceOf()를 써서 간단하게 sequnece를 만들 수 있습니다.

 

2. .asSequence()

Iteractor를 이미 다루고 있다면 .asSequence() 함수를 써서 Iterator를 Sequence로 변환할 수 있습니다.

 

3. generateSequence()

마지막으로 generateSequence()는 조금 복잡한 만큼 유연하게 sequence를 만들 수 있는데요, 2가지 인자를 받습니다. seed라고 불리는 초기값과, nextFunction이라 불리는 seed에서 시작해서 그 전 값에서 다음값을 계산할 수 있는 함수입니다.

fun <T : Any> generateSequence(
	seed: T?,
	nextFunction: (T) -> T?,
): Sequence<T>

 

예를들어, 짝수 sequence를 만든다면 아래와 같이 만들 수 있습니다.

generateSequence(2) { it + 2 }

🐜 무한 Sequence에서 일부 값 가져오기

마지막으로 무한 Sequence에 관한 얘기를 해 보겠습니다. 당연히 컴퓨터는 유한하기 때문에 진짜로 무한한 연산을 하는건 아니고, Sequence는 Lazy하게 동작하기 때문에 개념적으로 무한 Sequence를 만들 수 있습니다.

 

fun evenLessThan(max: Int): List<Int> {
	generateSequence(2) { it + 2 }
    	.takeWhile { it < max }
        .toList()
}

위 예제는 짝수 무한 Sequence에서 takeWhile을 써서 특정 값 미만의 모든 짝수 List를 가져오는 코드입니다.


 

반응형