Skip to content
Lesson 15 of 19

Step 1 of 5 · Reading · ~3 min

Learn

Collections

Sequences

Chain map and filter on a List and each step builds a whole new list before the next step starts. A Sequence does the opposite: it pulls one element all the way through the chain, then the next one. Same method names, completely different schedule.

Watch the difference

fun main() {
    val nums = listOf(1, 2, 3)

    println("-- list --")
    nums.map { println("map " + it); it * 2 }
        .filter { println("filter " + it); it > 2 }
        .first()

    println("-- sequence --")
    nums.asSequence()
        .map { println("map " + it); it * 2 }
        .filter { println("filter " + it); it > 2 }
        .first()
}

//> -- list --
//> map 1
//> map 2
//> map 3
//> filter 2
//> filter 4
//> filter 6
//> -- sequence --
//> map 1
//> filter 2
//> map 2
//> filter 4

The list version does all the mapping, then all the filtering, then throws away everything after the first match: six lambda calls to answer a question that needed two elements. The sequence version stops the instant first() is satisfied — four calls, and element 3 is never touched at all.

Intermediate and terminal operations

KindExamplesWhat it does
Intermediatemap, filter, take, sortedByadds a stage to the pipeline; runs nothing
TerminaltoList, sum, count, first, forEachpulls elements through and produces a result

That split is the whole model, and it has a sharp edge. A sequence with no terminal operation does nothing whatsoever:

fun main() {
    listOf(1, 2, 3).asSequence().map { println("seen " + it); it }
    println("done")
}

//> done

Not one seen line. The pipeline was built and then never run.

✓ Add a terminal operation and the work happens:

listOf(1, 2, 3).asSequence().map { println("seen " + it); it }.toList()

When is a sequence actually worth it?

SituationReach for
A handful of elements, one or two stepsList
A long chain over a large collectionSequence
You only need the first few resultsSequence
A source with no end, from generateSequenceSequence — a List could not exist

For small data a Sequence is usually slower: every element carries the cost of walking the whole pipeline, and a list has none of that per-element bookkeeping. Do not sprinkle .asSequence() everywhere. Switch in with .asSequence() when the chain is long or the source is big, and finish with a terminal call to come back to a real collection.

Your exercise

Sum of Squares of Evens reads a line of space-separated integers and prints the sum of the squares of the even ones.

filter, map and sum on the plain list are exactly right here — the input is one short line, so there is nothing for a sequence to save.

The mistake the grader catches lives in a hidden test that feeds 1 3 5 7. After the filter, nothing is left, and the expected answer is 0. sum() on an empty list returns 0, so it survives; reduce { a, b -> a + b } throws UnsupportedOperationException on an empty list and fails the test outright. Use sum(). Print one integer with no other text.

Up nextClasses and ConstructorsClasses and Inheritance

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…