Kotlin Tutorial · Functional Kotlin and Collections · Lesson 21 of 31
Kotlin Sequences
Process large or infinite data lazily with sequences instead of building intermediate lists.
Eager lists vs lazy sequences
List operations are eager: each step builds a full intermediate list. A sequence (asSequence()) is
lazy: elements flow through the whole chain one at a time, and processing stops as soon as the result is
known. The example counts how many elements each version touches.
fun main() {
var checked = 0
val firstEager = (1..1_000).map { checked++; it * it }.first { it > 50 }
println("list: $firstEager after $checked squares")
checked = 0
val firstLazy = (1..1_000).asSequence().map { checked++; it * it }.first { it > 50 }
println("sequence: $firstLazy after $checked squares")
}
Output
list: 64 after 1000 squares sequence: 64 after 8 squares
Run this on your computer — see “Get Started” for setup.
Generating sequences
generateSequence and sequence { yield(...) } create (possibly infinite) sequences; take what you need.
fun main() {
val powersOfTwo = generateSequence(1) { it * 2 }
println(powersOfTwo.take(8).toList())
val fibonacci = sequence {
var a = 0
var b = 1
while (true) {
yield(a)
val next = a + b
a = b
b = next
}
}
println(fibonacci.filter { it % 2 == 0 }.take(5).toList())
}
Output
[1, 2, 4, 8, 16, 32, 64, 128] [0, 2, 8, 34, 144]
Run this on your computer — see “Get Started” for setup.
Test yourself
When is a sequence better than a list for a chain of operations?
AlwaysFor large or infinite data, or when processing can stop earlyFor tiny listsWhen you need random access by index
Show answer
Answer: For large or infinite data, or when processing can stop early