Skip to content
Streams
step 1/5

Reading — step 1 of 5

Learn

~3 min readCollections

Streams

By now you'd solve "sum the squares of the even numbers" with a loop, an if, and an accumulator. Streams (Java 8+) flip the style: instead of describing HOW to loop, you declare WHAT happens to the data — filter these, transform those, aggregate the result. The pipeline reads like the sentence you'd say out loud.

import java.util.Arrays;

int[] nums = {1, 2, 3, 4, 5};

int result = Arrays.stream(nums)      // source: an IntStream over the array
    .filter(n -> n % 2 == 0)          // keep only evens: 2, 4
    .map(n -> n * n)                  // square each: 4, 16
    .sum();                           // aggregate: 20

The three-part pipeline

  1. SourceArrays.stream(array), list.stream(), IntStream.range(0, n), ...
  2. Intermediate operationsfilter (keep elements passing a test), map (transform each), sorted, distinct, limit, ... Each returns a new stream, so they chain.
  3. Terminal operationsum(), count(), collect(...), forEach(...), findFirst(). Exactly one, at the end.

Streams are lazy: filter and map do nothing on their own. The pipeline only runs when the terminal operation asks for the result. And streams never mutate their source — nums is untouched afterward.

Lambdas — inline functions

n -> n % 2 == 0 is a lambda: parameters, arrow, expression. (a, b) -> a + b takes two. When a lambda just calls one existing method, a method reference is shorter still: Integer::parseInt instead of s -> Integer.parseInt(s) — the starter uses exactly that to parse your input line.

IntStream vs Stream<Integer> — where sum() lives

There are two flavors of stream, and sum() exists on only one:

Arrays.stream(nums)               // int[] source → IntStream (primitive ints)
    .map(n -> n * n).sum();       // sum() exists — no boxing, fast

List.of(1, 2, 3).stream()         // collection → Stream<Integer> (boxed objects)
    .sum();                       // compile error! Stream<Integer> has no sum()

To sum a Stream<Integer>, bridge with .mapToInt(Integer::intValue) first. Your starter hands you an int[], so Arrays.stream(nums) is already an IntStream and the pipeline above just works.

The trap: a missing stage

Each stage is easy; the bug is omitting one. Both of these compile, and both are wrong:

Arrays.stream(nums).map(n -> n * n).sum();
// forgot filter → squares EVERYTHING: 1+4+9+16+25 = 55

Arrays.stream(nums).filter(n -> n % 2 == 0).sum();
// forgot map → sums the evens unsquared: 2+4 = 6

Wrong answers with plausible shapes — exactly what graders exist to catch.

Your exercise

Read a line of space-separated integers (the starter already builds int[] nums), then print the sum of the squares of the EVEN numbers using a stream pipeline:

System.out.println(
    Arrays.stream(nums)
        .filter(n -> n % 2 == 0)
        .map(n -> n * n)
        .sum()
);

For 1 2 3 4 5 the grader expects 20 (that's 4 + 16). The mistake it will catch: dropping the filter stage — if your output is 55, you squared and summed all five numbers. And keep the all-odds case in mind: 1 3 5 7 has no evens, so the pipeline correctly sums nothing and prints 0 — an empty IntStream's sum() is 0, no special-casing needed.

Discussion

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

Sign in to post a comment or reply.

Loading…