Calling .map { }.filter { } on a List is EAGER — map fully processes and allocates a complete new list before filter even starts on it. asSequence() converts a collection to a Sequence, where the same chain becomes LAZY: each element flows through map, then filter, then reaches the terminal operation one at a time, with no intermediate list ever fully materialized — genuinely faster and more memory-efficient specifically when a large collection is involved or when a terminal operation like first {} can stop early. takeIf returns the receiver if a predicate is true (or null otherwise); takeUnless is its exact inverse — both let a conditional check be chained inline rather than requiring a separate if statement.
List operations are eager: every step fully materializes
map runs across ALL one million elements, allocating a full new list, before filter even starts — wasteful when only the first matching result is actually needed.
val numbers = (1..1_000_000).toList()
val result = numbers
.map { it * 2 } // fully processes ALL 1,000,000 elements first
.filter { it > 100 } // THEN filters the entire resulting list
.first() // only needed the FIRST one — but both steps already ran fullySequence: lazy, element-by-element
Each number flows through map, then filter, then reaches first() one at a time — processing stops the INSTANT a match is found, potentially touching only a handful of elements instead of a million.
val numbers = (1..1_000_000).asSequence()
val result = numbers
.map { it * 2 } // lazy — nothing runs yet
.filter { it > 100 } // still lazy
.first() // NOW everything runs, element-by-element, stopping at the first matchtakeIf and takeUnless: inline conditional checks
Both let a condition be woven directly into an expression chain, rather than requiring a separate if block that breaks the flow — genuinely convenient combined with a following ?.let or ?: for a fallback.
val number = 15
val evenNumber = number.takeIf { it % 2 == 0 } // null, since 15 is odd
println(evenNumber ?: "not even") // "not even"
val validated = number.takeUnless { it < 0 } // 15, since it's NOT negative
println(validated)