Advanced

Streams and Lambdas

Write concise data processing with lambdas and streams.

What you will see

10 1,2,3,4

About 2 min of reading

Try It

Process data concisely with streams and lambdas. Filter a list down, transform with map, collect the result, then fold a whole list into a sum and a joined string.

1

Chain stream, filter, and map, then collect into a new list. Filter keeps items longer than three characters and map upper-cases them, read the single collected element.

import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; class Main { public static void main(String[] args) { List names = Arrays.asList("Ada", "Bob", "Christopher"); List upper = names.stream() .filter(n -> n.length() > 3) .map(String::toUpperCase) .collect(Collectors.toList()); System.out.println(upper); } }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
[CHRISTOPHER]
filter and map are lazy: nothing runs until collect forces the pipeline. List.of is not available on Java 8, so this uses Arrays.asList.
2

Reduce a stream to a single value. Count the integers with mapToInt...sum, then turn them back into a comma-separated string with collect...joining. Two different reductions, one source.

import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; class Main { public static void main(String[] args) { List nums = Arrays.asList(1, 2, 3, 4); int sum = nums.stream().mapToInt(Integer::intValue).sum(); String joined = nums.stream().map(String::valueOf) .collect(Collectors.joining(",")); System.out.println(sum); System.out.println(joined); } }

Before you run it, say out loud what it will print. Then open the answer.

What it prints
10 1,2,3,4
sum is an int-typed terminal that folds to a primitive, while joining collects to a String. Pick the terminal that matches the result you want.

Data Flow

A stream pulls data through a lazy pipeline of intermediate operations, then a terminal operation collects the result.
1 Create a stream from a source
↓
2 Filter/map lazily stage operations
↓
3 Terminal operation triggers the pipeline
↓
4 Results collected or reduced
Why this works
Method references

When a lambda just calls a method, use a method reference:

names.map(String::toUpperCase);   // same as n -> String.toUpperCase(n)
nums.forEach(System.out::println);

ClassName::methodName is sugar for a lambda that delegates. It is more concise and often faster.

When you have a choice

Lazy vs eager operations

Stream operations are lazy: intermediate operations (filter, map) are not executed until a terminal operation (collect, forEach, sum) triggers them. This lets the pipeline fuse work efficiently:

nums.stream()
    .filter(n -> { System.out.println("filter"); return n > 2; })
    .map(n -> n * 2)
    .count();   // only runs when count() triggers the pipeline

The lambda bodies only run once the terminal operation starts the pipeline.

Examples

Lambda expressions

Anonymous functions

// Before
Comparator<String> byLen = new Comparator<String>() {
    public int compare(String a, String b) {
        return Integer.compare(a.length(), b.length());
    }
};

// After
Comparator<String> byLen = (a, b) ->
    Integer.compare(a.length(), b.length());

A lambda is a compact anonymous function. The arrow -> separates parameters from the body.

Filtering and mapping

Data processing

List<String> names = List.of("Ada", "Bob", "Cy");
List<String> upper = names.stream()
    .filter(n -> n.length() > 3)
    .map(String::toUpperCase)
    .collect(Collectors.toList());
// ["ADA", "BOB"]

stream() begins processing. filter keeps matching items; map transforms them; collect gathers the result.

Reducing to a value

Folding a stream

List<Integer> nums = List.of(1, 2, 3, 4);
int sum = nums.stream()
    .mapToInt(Integer::intValue)
    .sum();   // 10

String joined = nums.stream()
    .map(String::valueOf)
    .collect(Collectors.joining(","));   // "1,2,3,4"

sum, max, min, and collect reduce a stream to a single result or a collection.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Collections Framework
Previous Lesson
Collections Framework
Next Lesson
Custom Exceptions and Design
Custom Exceptions and Design →