reduce: Many Values Into One

Streams · lesson 7 of 42 · 4 min read

Fold a whole stream into a single value, with or without a starting identity.

Open this lesson in the learning hub

Key points

  • reduce folds a stream into one value by applying a two-argument function over and over.
  • The one-argument form returns an Optional, because an empty stream has no answer.
  • The two-argument form takes an identity: 0 for sum, 1 for product, an empty string for concat. Empty stream gives back the identity.
  • Your operator must be associative, or a parallel run will disagree with a sequential one.
  • For plain sums and averages prefer mapToInt(...).sum(): clearer, and no boxing.

Example

import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> nums = List.of(3, 1, 4, 1, 5, 9);

        // One argument: no starting value, so you get an Optional.
        Optional<Integer> max = nums.stream().reduce(Integer::max);

        // Two arguments: identity + combiner. Always returns a value.
        int sum = nums.stream().reduce(0, Integer::sum);
        int product = nums.stream().reduce(1, (a, b) -> a * b);

        System.out.println("max        : " + max.orElse(-1));
        System.out.println("sum        : " + sum);
        System.out.println("product    : " + product);
        System.out.println("empty sum  : " + Stream.<Integer>empty().reduce(0, Integer::sum));
        System.out.println("empty max  : " + Stream.<Integer>empty().reduce(Integer::max).isPresent());
        System.out.println("longest    : " + Stream.of("ada", "grace", "al")
                .reduce("", (a, b) -> a.length() >= b.length() ? a : b));
    }
}

Give reduce an identity and an associative operator, and it parallelises for free.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.