SyntaxStudy
Sign Up
Kotlin Sequences for Lazy Evaluation
Kotlin Beginner 1 min read

Sequences for Lazy Evaluation

When chaining multiple collection operations, Kotlin evaluates each intermediate result eagerly by default: filter creates a new list, then map creates another list, and so on. For large collections this produces unnecessary intermediate allocations. Sequences solve this by evaluating operations element-by-element in a lazy pipeline. Each element passes through all operations before the next element starts. You convert a collection to a sequence with asSequence() and back to a list with toList(). The sequence is only evaluated when a terminal operation is called. Sequences are also useful when generating infinite streams of values using generateSequence() or the sequence builder. The take(n) terminal operation limits how many elements are consumed, allowing you to work safely with unbounded sequences.
Example
fun main() {
    val numbers = (1..1_000_000).toList()

    // Eager — creates two intermediate lists
    val eagerResult = numbers
        .filter  { it % 2 == 0 }
        .map     { it * it }
        .take(5)
    println("Eager:  $eagerResult")

    // Lazy — no intermediate lists; stops after 5 elements found
    val lazyResult = numbers.asSequence()
        .filter  { it % 2 == 0 }
        .map     { it * it }
        .take(5)
        .toList()
    println("Lazy:   $lazyResult")

    // generateSequence — infinite Fibonacci sequence
    val fibonacci: Sequence<Long> = generateSequence(Pair(0L, 1L)) {
        Pair(it.second, it.first + it.second)
    }.map { it.first }

    println(fibonacci.take(10).toList())
    // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

    // sequence builder with yield
    val evens = sequence {
        var n = 0
        while (true) {
            yield(n)
            n += 2
        }
    }
    println(evens.take(6).toList())   // [0, 2, 4, 6, 8, 10]

    // Sequence of file lines (hypothetical large file)
    val words = sequenceOf("the", "quick", "brown", "fox", "jumps")
    val result = words
        .filter { it.length >= 4 }
        .map    { it.replaceFirstChar { c -> c.uppercase() } }
        .toList()
    println(result)   // [Quick, Brown, Jumps]
}