What is a Kotlin Flow, and how does it relate to a regular list and to reactive streams like RxJava's Observable?
answer
- List = all values now; Flow = values over time
- Sequence is lazy+sync; Flow is lazy+async (can suspend)
- Flow = Kotlin's Observable/Flux, built on coroutines
- emit() pushes, collect() pulls/runs
- Suspension instead of callbacks/Schedulers
basics
~10 sA Flow is a stream of values produced over time, one after another. Unlike a list, the values can arrive asynchronously without blocking. It is Kotlin's coroutine-based answer to reactive streams.
solid answer
~40 sFlow<T> is an asynchronous data stream that emits zero or more values of type T over time and then completes (or fails). A List<T> holds all values at once in memory; a Flow produces them lazily, possibly asynchronously, using suspend functions so it never blocks a thread. It plays the same role as RxJava's Observable or Reactor's Flux: representing a sequence of events you react to. The key Kotlin difference is that Flow is built on coroutines and structured concurrency instead of callbacks and Schedulers — emission and collection happen inside coroutines, and suspension (not buffering or callbacks) is the primitive used to coordinate producer and consumer speed.
code
kotlin · 8 linesval temps: Flow<Int> = flow {
while (true) {
emit(readSensor()) // suspend network/IO call, no blocking
delay(1000)
}
}
temps.collect { temp -> println("Now: $temp") }go deeper
Knows Flow is an async stream of values over time, unlike a List, and that collect consumes it.
Articulates the Sequence (sync, can't suspend) vs Flow (async, can suspend) distinction and maps Flow onto Observable/Flux.
Explains that suspension (not callbacks/Schedulers) is the coordination primitive and ties Flow to structured concurrency.
Frames Flow as a design choice: pushing reactive semantics onto suspend/coroutines to unify async code, with implications for tooling, debugging, and interop with Rx/Reactor.
## What a Flow is `Flow<T>` (from `kotlinx.coroutines.flow`) is an **asynchronous sequence**: it produces a stream of values of type `T`, in order, over time, and then either completes normally or completes with an exception. It is the coroutine-native equivalent of a reactive stream. ## Flow vs List vs Sequence - A `List<T>` is **eager and finite**: every element already exists in memory. - A `Sequence<T>` is **lazy but synchronous**: elements are computed on demand, but each step runs on the calling thread and **cannot suspend** (you can't call `suspend` functions inside a sequence's `yield`). - A `Flow<T>` is **lazy and asynchronous**: producing the next element may run a `suspend` function (e.g. a network call) without blocking the thread. ## Flow vs reactive streams (Rx/Reactor) Flow occupies the same niche as RxJava's `Observable`/`Flowable` or Project Reactor's `Flux`: a push-style stream of events you transform with operators (`map`, `filter`, etc.). The conceptual differences: - Flow uses **coroutines and `suspend`** for asynchrony, so there are no callbacks and no `Scheduler` objects. - Backpressure is handled implicitly by **suspension**: a slow collector simply suspends the producer. - Flow is integrated with **structured concurrency**, so cancellation and scope are inherited automatically. ```kotlin import kotlinx.coroutines.flow.* val numbers: Flow<Int> = flow { for (i in 1..3) { emit(i) // push a value to the collector } } // nothing runs until someone collects: numbers.collect { println(it) } // 1, 2, 3 ``` The `flow { ... }` builder is a coroutine; `emit` sends a value downstream; `collect` is a `suspend` terminal operator that runs the stream.
- Can you build a Flow from a fixed set of values without the flow { } builder?Yes — flowOf(1, 2, 3) or listOf(1,2,3).asFlow() create a Flow from known values.
- Why can't a regular Sequence call a suspend function?Sequence's iterator runs synchronously on the calling thread; it has no coroutine context, so suspension points aren't allowed. Flow's builder is a coroutine, so it can suspend.
A List is a delivered package of all items; a Flow is a conveyor belt that hands you items one at a time as they're produced.
saying these in an interview costs you the question
- Saying a Flow holds all its values in memory like a List
- Claiming Flow blocks the thread while waiting for the next value
- Confusing Flow with Sequence and saying both can suspend
- Thinking Flow uses callbacks/listeners under the hood
- Saying you must subscribe with a callback object like in RxJava