Java Tutorial · Advanced Java · Lesson 32 of 37

Java Streams

Process collections with filter, map, reduce, collect and groupingBy.

The Stream API

Streams process collections in a declarative pipeline: a source, zero or more intermediate operations (filter, map, sorted…) and one terminal operation (toList, count, collect…). Streams don't modify the source.

Example 1
import java.util.List;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 8, 1, 9, 4);
        List<Integer> result = nums.stream()
            .filter(n -> n % 2 == 0)
            .map(n -> n * n)
            .sorted()
            .toList();
        System.out.println(result);
        System.out.println(nums.stream().mapToInt(Integer::intValue).sum());
        System.out.println(nums.stream().reduce(0, Integer::sum));
        System.out.println(nums.stream().anyMatch(n -> n > 8) + " " + nums.stream().allMatch(n -> n > 0));
        System.out.println(IntStream.rangeClosed(1, 5).boxed().toList());
    }
}

Output

[4, 16, 64]
29
29
true true
[1, 2, 3, 4, 5]

Run this on your computer — see “Get Started” for setup.

Collectors

Collectors.groupingBy, joining, toMap and averagingDouble turn streams into maps and strings:

Example 2
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Order> orders = List.of(
            new Order("Ada", "books", 30), new Order("Lin", "games", 60),
            new Order("Ada", "games", 45), new Order("Sam", "books", 15));
        Map<String, Double> revenueByCategory = orders.stream()
            .collect(Collectors.groupingBy(Order::category, TreeMap::new, Collectors.summingDouble(Order::total)));
        System.out.println(revenueByCategory);
        String customers = orders.stream().map(Order::customer).distinct().sorted().collect(Collectors.joining(", "));
        System.out.println(customers);
        System.out.println(orders.stream().mapToDouble(Order::total).average().orElse(0));
    }

    record Order(String customer, String category, double total) {}
}

Output

{books=45.0, games=105.0}
Ada, Lin, Sam
37.5

Run this on your computer — see “Get Started” for setup.

Practise with the Java streams report problem.

Test yourself

Which kind of stream operation produces the final result and ends the pipeline?

  1. An intermediate operation
  2. A terminal operation
  3. A source
  4. A collector constructor
Show answer

Answer: A terminal operation

Practice next