Terminal operations trigger execution in Kotlin - Time & Space Complexity
When working with database queries or streams, some operations only run when we ask for results.
We want to see how the time it takes grows when the final action triggers the work.
Analyze the time complexity of the following Kotlin code snippet.
val data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = data.asSequence()
.filter { it % 2 == 0 }
.map { it * 2 }
.toList() // terminal operation triggers execution
This code creates a sequence from a list, applies filters and maps lazily, then collects results with a terminal operation.
Look at what repeats when the terminal operation runs.
- Primary operation: The filter runs once for each item and the map once for each even item when toList() is called.
- How many times: Each element in the original list is checked (filtered) exactly once; only even elements are transformed (mapped).
As the list gets bigger, the work grows in a simple way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 filter + 5 map = 15 operations |
| 100 | 100 filter + 50 map = 150 operations |
| 1000 | 1000 filter + 500 map = 1500 operations |
Pattern observation: The total work grows directly with the number of items.
Time Complexity: O(n)
This means the time to get results grows in a straight line with the number of items.
[X] Wrong: "The filter and map run immediately when defined."
[OK] Correct: They actually wait until the terminal operation runs, so no work happens before then.
Understanding when work actually happens helps you write efficient queries and explain your code clearly.
"What if we replaced toList() with first()? How would the time complexity change?"