스트림은 핫 스트림과 콜드 스트림으로 나뉨
종류 | 데이터 생성 시점 | 특징 | |
---|---|---|---|
핫 스트림 | Channel, List, Set 등 | 소비 시점과 무관 | - 중간에 생성되는 값들을 보관 |
fun m(i: Int): Int {
print("m$i ")
return i * i
}
fun f(i: Int): Boolean {
print("f$i ")
return i >= 10
}
fun main() {
listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.map { m(it) }
.find { f(it) }
.let { print(it) }
// m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 f1 f4 f9 f16 16
println()
sequenceOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.map { m(it) }
.find { f(it) }
.let { print(it) }
// m1 f1 m2 f4 m3 f9 m4 f16 16
}
플로우를 생성하는 가장 일반적인 방법은 flow
를 사용하는 것
val flow = flow {
while (true) {
val x = nextValue()
emit(x)
}
}
produce
함수와 비교를 해보자.
produce
는 CoroutineScope 확장 함수로 정의되어 있는 코루틴 빌더가 되어야 함
flow
는 빌더가 아니며 단지 최종 연산이 호출될 때 원소가 어떻게 생성되어야 하는지 정의한 것
플로우는 비동기적으로 계산해야 할 값의 스트림이다.
원소들을 모으는 역할이 기본이며, 플로우의 끝에 도달할 때까지 각 값을 처리하는 것을 의미
유일한 멤버 함수로 collect
를 갖고 있음
List, Set은 모든 원소의 계산이 완료된 컬렉션이다.
원소를 하나씩 계산할 때는, 원소가 나오자마자 바로 얻을 수 있는 Sequence
를 사용하는 것이 좋다.
시퀀스는 연산이 많거나 블로킹 연산을 처리할 때마다 값을 계산하는 플로우를 나타내기 적절하다.