App노자
[Kotlin] sequence (시퀀스) 본문
1. sequence란?
sequence는 순차적인 컬렉션으로 요소의 크기를 특정하지 않고 나중에 결정할 수 있는 컬렉션이다
특정 파일을 줄 단위로 읽어서 요소를 만들 때 해당 파일의 끝을 모르면 줄이 언제 끝날지 알 수 없는 경우에 사용할 수 있다
처리 중에는 계산하고 있지 않다가 toList()나 count() 같은 최종 연산에 의해 결정된다
https://kotlinlang.org/docs/sequences.html
Sequences | Kotlin
kotlinlang.org
2. sequence 생성
//sequenceOf()
val numbersSequence = sequenceOf("four", "three", "two", "one")
요소를 인수로 나열하는 sequenceOf() 함수로 생성하는 방식이다
//asSequence()
val numbers = listOf("one", "two", "three", "four")
val numbersSequence = numbers.asSequence()
Iterable개체를 이용해 생성할 때는 asSequence() 함수로 개체에서 시퀀스를 만들 수 있다
//generateSequence()
fun main() {
// 시드값 1을 시작으로 1씩 증가하는 시퀀스 정의
val nums: Sequence<Int> = generateSequence(1) { it + 1 }
// take()를 사용해 원하는 개수의 요소를 획득
// toList()를 사용해 List 컬렉션으로 반환
println(nums.take(10).toList())
val oddNumbersLessThan10 = generateSequence(1) { if (it < 8) it + 2 else null }
println(oddNumbersLessThan10.count())
}
특정 값을 생성하는 함수를 기반으로 sequence를 작성하려면 generateSequence()를 사용한다
이때 시드(seed) 인수에 의해 시작 요소의 값이 결정된다
제공된 함수가 반환되면 시퀀스 생성이 중지된다
따라서 무한한 시퀀스가 될 수 있는데 유한한 시퀀스를 만들려면
필요한 마지막 요소 다음에 generateSequence() 를 반환하는 함수를 제공하거나 take를 통해 필요한 값만 획득한다
take의 인자를 통해 원하는 개수만큼 요소가 저장되며 toList()등을 통해 컬렉션으로 반환이 가능하다
fun main() {
val squares = generateSequence(1) {it + 1}.map {it * it}
println(squares.take(10).toList())
val oddSquares = squares.filter {it % 2 != 0}
println(oddSquares.take(5).toList())
}
주어신 식에 따라 새로운 컬렉션을 반환하는 map이나 filter 같은 연산도 사용할 수 있다
map, filter 등이 호출될 때, Collection에서는 바로 수행되어 실행할 때마다 새로운 List를 생성해 반환하며 전체 원소를 순회하지만, Sequence에서는 하나의 구문이 끝날 때 중간결과로 새로운 List를 계속해서 만들어 낸다
3. sequence 요소 값 가져오기
fun main() {
// 단순 메서드 체이닝을 사용할 때
val list1 = listOf(1, 2, 3, 4, 5)
val listDefault = list1
.map { println("map($it) "); it * it } // ①
.filter { println("filter($it) "); it % 2 == 0 } // ②
println(listDefault)
println()
// asSequence()의 사용
val listSeq = list1.asSequence()
.map { print("map($it) "); it * it } // ①
.filter { println("filter($it) "); it % 2 == 0 } // ②
.toList() // ③
println(listSeq)
}
중간 연산 결과 없이 한 번에 끝까지 연산한 후 결과를 반환하려면 asSequence를 사용할 수 있다
map, filter를 메서드 체이닝 해서 사용할 경우 순차적 연산이기 때문에 시간이 걸릴 수 있지만
asSequence()의 경우 1번 과정과 2번 과정에서 연산을 하는 것이 아니라 3번 과정에서 최종적 결과를 List목록으로 반환을 할 때
모든 연산이 수행되고 결과물이 새로운 리스트 listSeq에 지정된다
순차적으로 연산을 할 때와 달리 map의 수행결과를 새로운 List에 만들고
이것을 다시 짝수 인지 판별해 리스트를 만드는 과정이 없다
병렬처리를 하기 때문에 요소의 개수가 많을 때 속도나 메모리 측면에서 횔씬 좋은 성능을 낼 수 있다
'Android > Kotlin' 카테고리의 다른 글
[Kotlin] 지연 초기화 (0) | 2023.08.05 |
---|---|
[Kotlin] 컬렉션의 확장 함수 (0) | 2023.08.04 |
[Kotlin] Set과 Map (0) | 2023.07.30 |
[Kotlin] List (0) | 2023.07.22 |
[Kotlin] Array 클래스 (0) | 2023.07.21 |