kotlinintermediate
Sequences — Lazy Evaluation for Large Data
Process large datasets efficiently with lazy sequences: generateSequence, yield, and custom iterators.
kotlinPress ⌘/Ctrl + Shift + C to copy
fun main() {
// Sequence vs List — lazy vs eager
println("--- Eager (List) ---")
val eagerResult = (1..10)
.filter { print("filter($it) "); it % 2 == 0 }
.map { print("map($it) "); it * 10 }
.first()
println("\nEager result: $eagerResult") // processes ALL then takes first
println("\n--- Lazy (Sequence) ---")
val lazyResult = (1..10).asSequence()
.filter { print("filter($it) "); it % 2 == 0 }
.map { print("map($it) "); it * 10 }
.first()
println("\nLazy result: $lazyResult") // stops at first match!
// generateSequence
println("\n--- Generate ---")
val powers = generateSequence(1) { it * 2 }
println("Powers of 2: ${powers.take(10).toList()}")
// Fibonacci
val fib = generateSequence(Pair(0L, 1L)) { (a, b) -> Pair(b, a + b) }
.map { it.first }
println("Fibonacci: ${fib.take(15).toList()}")
// Collatz sequence
fun collatz(n: Long) = generateSequence(n) { current ->
when {
current <= 1L -> null // terminate
current % 2 == 0L -> current / 2
else -> current * 3 + 1
}
}
println("Collatz(27): ${collatz(27).toList().size} steps")
// sequence builder with yield
println("\n--- Yield ---")
val custom = sequence {
yield(1)
yield(2)
yieldAll(listOf(3, 4, 5))
yieldAll(generateSequence(6) { it + 1 })
}
println("Custom: ${custom.take(10).toList()}")
// File-like line processing (simulated)
println("\n--- Processing ---")
val lines = sequence {
yield("# header")
yield("name,age")
yield("Alice,30")
yield("Bob,25")
yield("# comment")
yield("Charlie,35")
}
data class Person(val name: String, val age: Int)
val people = lines
.filter { !it.startsWith("#") }
.drop(1) // skip header
.map { line ->
val (name, age) = line.split(",")
Person(name, age.toInt())
}
.toList()
println("People: $people")
// Chunked processing
println("\n--- Chunked ---")
(1..20).asSequence()
.chunked(5)
.forEach { chunk ->
println("Processing batch: $chunk (sum=${chunk.sum()})")
}
// Benchmark: Sequence vs List for large data
println("\n--- Benchmark ---")
val size = 1_000_000
val listTime = kotlin.system.measureTimeMillis {
(1..size).filter { it % 3 == 0 }.map { it * 2L }.take(100).sum()
}
val seqTime = kotlin.system.measureTimeMillis {
(1..size).asSequence().filter { it % 3 == 0 }.map { it * 2L }.take(100).sum()
}
println("List: ${listTime}ms, Sequence: ${seqTime}ms")
}Use Cases
- Processing large datasets without loading all into memory
- Infinite series generation
- Efficient pipeline processing with early termination
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinintermediate
Sequence Generators with yield
Create lazy sequences with sequence builders, yield, yieldAll, and custom infinite generators.
Best for: Lazy paginated API consumption
#kotlin#sequences
scalaintermediate
Collection Views for Lazy Operations
Use collection views for efficient lazy transformations: avoid intermediate collections and improve performance.
Best for: Memory-efficient data processing
#scala#views
kotlinbeginner
Null Safety — Elvis, Safe Call, and let
Master Kotlin null safety: safe calls, Elvis operator, let/also scoping, and smart casts.
Best for: Safe navigation through nullable chains
#kotlin#null-safety
kotlinbeginner
Data Classes — Copy, Destructure, and Equals
Use data classes for immutable models: auto-generated equals, hashCode, copy, and destructuring.
Best for: Immutable domain models and DTOs
#kotlin#data-class