liveBook · Manning

Intermediate operation

As explained in Kotlin in Action, 2E

An intermediate operator is a Flow transformation that collects values from an upstream flow and emits transformed or otherwise produced values to a downstream flow.

An intermediate operation transforms a Kotlin Flow into another Flow. It receives values from an upstream flow and returns a downstream flow, allowing operators such as map, filter, and onEach to form a chain. section 17.2 section 17.5

A custom rolling-average operator

fun Flow<Double>.averageOfLast(n: Int): Flow<Double> = flow { val numbers = mutableListOf<Double>() collect { if (numbers.size >= n) numbers.removeFirst() numbers.add(it) emit(numbers.average()) } } flowOf(1.0, 2.0, 30.0, 121.0) .averageOfLast(3) .collect { print("$it ") } // 1.0 1.5 11.0 51.0 The operator collects upstream values, maintains a bounded list, and emits a transformed value downstream. Wrapping collect inside flow keeps the operator cold: work begins only when collect is called on the returned Flow. section 17.3

Intermediate operations have three practical properties:

  • Return another Flow rather than an immediate result. section 17.1
  • Remain cold: calling an operator does not execute its behavior until a terminal operator such as collect runs, including when the upstream flow is hot. section 17.2
  • Can transform values, perform side effects, manage execution context, or hook into lifecycle phases through operators such as transform, flowOn, onStart, onEach, onCompletion, and onEmpty. section 17.5 section 17.2.3
Figure 17.1 You distinguish between intermediate and terminal flow operators. Where intermediate operators return a modified flow, terminal operators return an actual result. They do so by executing the code in the flow.
CH17_F01_Isakova

Use the diagram to distinguish an intermediate operator’s modified downstream Flow from a terminal operator’s executed result. section 17.1

How Kotlin in Action, 2E covers it

How deep it goes
Explains upstream/downstream flow, cold execution, lifecycle behavior, and custom implementation through flow and collect.
Examples
Demonstrates map, filter, onEach, onStart, onCompletion, onEmpty, and a rolling average over the last n values.
What it assumes
Assumes familiarity with flows and terminal collection while reinforcing upstream/downstream relationships and deferred execution.
What you can do after
Apply via Kotlin Flow operators or build custom transformations with flow, collect, and emit.
How it connects
Connects Flow to sequences, collections, terminal operators, cold flows, hot flows, flow builders, and Kotlin coroutines.

Also explained in

Compare how 3 books explain intermediate operation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Kotlin in Action, 2E. The section links point to the parts of the book it draws on.