collect
- Kotlin course
- Intermediate
- Lesson 90/116
- 5 min
Learn to consume Flows with collect.
collect: Terminal operator
collect is a terminal operator: it starts the flow and consumes its values. Unlike intermediate operators (map, filter), without collect the flow does nothing. This is why a Flow is called cold.
fun numbers(): Flow<Int> = flowOf(1, 2, 3)
fun main() = runBlocking {
numbers().collect { println(it)
}
}collect is a suspend function; it can only be called inside a coroutine. The lambda runs once for each emitted value, in order. When the flow ends, collect returns and main continues.
collect inside a coroutine
Because collect is a suspend function, it can only be called from inside a coroutine. Using runBlocking { ... } in main bridges the flow to a synchronous call. The program then waits until the flow finishes.
fun main() = runBlocking {
var sum = 0
numbers().collect { sum += it }
println(sum)
}Here collect runs sum += it for each value; when the flow ends, println(sum) runs. Mutating an outer variable (here sum) from the lambda is safe for small flows. For more complex cases prefer operators like fold.
Practice Collect values into a sum
Define fun numbers(): Flow<Int> = flowOf(1, 2, 3). Mark main with runBlocking. Inside it initialise var sum = 0; collect with numbers().collect { sum += it }; print the result with println(sum).
Starter code
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
// numbers function: return a Flow<Int> of 1, 2, 3
// main: inside runBlocking, accumulate values into sum
// print sum with println
fun main() = runBlocking {
// write here
}Sample solution
fun numbers(): Flow<Int> = flowOf(1, 2, 3)
fun main() = runBlocking {
var sum = 0
numbers().collect { sum += it }
println(sum)
}Expected output
6
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What does flow.collect { ... } do?
- Consumes the flow; runs the lambda for each value Correct answer
- Converts the flow to a list
- Starts the flow but receives no values
- Cancels the flow
Explanation: collect is terminal; it runs the lambda for each emitted value.
2 Match the collect concepts
| Term | Meaning |
|---|---|
collect { } |
Consumer |
terminal |
Final operation |
suspend |
Pausing |
println(it) |
Prints the value |
3 Consume the flow
fun main() = runBlocking {
numbers().____ { println(it) }
}
fun main() = runBlocking {
numbers().collect { println(it) }
}
Explanation: collect is the terminal operator that consumes a flow.