Sequences

A Sequence evaluates lazily: elements flow through the pipeline one at a time, and operations run only as far as needed. This avoids building intermediate collections and enables early termination.

Eager vs lazy

// Eager: each step builds a full new list
val eager = listOf(1, 2, 3, 4, 5)
    .map { it * it }       // [1, 4, 9, 16, 25]
    .filter { it > 5 }     // [9, 16, 25]
    .first()               // 9  — but all elements were processed twice

// Lazy: elements pulled on demand, stops at the first match
val lazy = listOf(1, 2, 3, 4, 5)
    .asSequence()
    .map { it * it }
    .filter { it > 5 }
    .first()               // 9  — only processes 1, 2, 3

With the sequence, map and filter run only for the elements needed to produce the first result.

Creating sequences

sequenceOf(1, 2, 3)
listOf(1, 2, 3).asSequence()

generateSequence(1) { it * 2 }   // infinite: 1, 2, 4, 8, ...
    .take(5)
    .toList()                    // [1, 2, 4, 8, 16]

generateSequence plus take is a common way to work with infinite streams safely.

Terminal vs intermediate operations

  • Intermediate (map, filter, take) are lazy and return a Sequence.
  • Terminal (toList, sum, first, count) trigger evaluation.

A sequence does nothing until a terminal operation is called.

When to use which

Use a List Use a Sequence
Small collections Large or huge collections
Few operations Long operation chains
You need the intermediate results You only need the final result
Infinite or generated data

For small lists, eager operations are often faster (no per-element iterator overhead). Reach for sequences when data is large or chains are long.

Exercises

  1. Use generateSequence to produce the first 10 powers of two.

  2. Write firstSquareOver(limit: Int): Int that returns the first perfect square (1, 4, 9, …) strictly greater than limit, using a sequence.

    Solution
   fun firstSquareOver(limit: Int): Int =
       generateSequence(1) { it + 1 }
           .map { it * it }
           .first { it > limit }
   

</details>

This solution is in examples/core/part4/ and is tested by CI.


Previous: Collection Operations · Next: Generics


Back to top

Kotlin & Android Programming Guide is not affiliated with JetBrains or Google. Content is provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.