0
0
JavaHow-ToBeginner · 3 min read

How to Use Stream Reduce in Java: Simple Guide with Examples

In Java, stream.reduce() combines elements of a stream into a single result by repeatedly applying a function. You can use it with or without an initial identity value to sum, multiply, or merge elements simply and efficiently.
📐

Syntax

The reduce method has two common forms:

  • Optional reduce(BinaryOperator<T> accumulator): Combines elements using the accumulator function, returns an Optional because the stream might be empty.
  • T reduce(T identity, BinaryOperator<T> accumulator): Uses an identity value as a starting point and combines elements, always returns a result.

The accumulator is a function that takes two elements and returns one combined element.

java
Optional<T> reduce(BinaryOperator<T> accumulator)

T reduce(T identity, BinaryOperator<T> accumulator)
💻

Example

This example shows how to sum a list of integers using reduce with and without an identity value.

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

public class StreamReduceExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // Using reduce with identity
        int sumWithIdentity = numbers.stream()
            .reduce(0, (a, b) -> a + b);

        // Using reduce without identity (returns Optional)
        Optional<Integer> sumWithoutIdentity = numbers.stream()
            .reduce((a, b) -> a + b);

        System.out.println("Sum with identity: " + sumWithIdentity);
        System.out.println("Sum without identity: " + sumWithoutIdentity.orElse(0));
    }
}
Output
Sum with identity: 15 Sum without identity: 15
⚠️

Common Pitfalls

Common mistakes when using reduce include:

  • Not providing an identity value when the stream might be empty, leading to an empty Optional.
  • Using a non-associative accumulator function, which can cause incorrect results.
  • Confusing reduce with collect for mutable reductions.

Always ensure your accumulator function is associative and consider using identity when you want a guaranteed result.

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

public class ReducePitfall {
    public static void main(String[] args) {
        List<Integer> emptyList = Collections.emptyList();

        // Wrong: no identity, empty stream leads to empty Optional
        Optional<Integer> result = emptyList.stream().reduce((a, b) -> a + b);
        System.out.println("Result without identity on empty list: " + result);

        // Right: provide identity to get a default value
        int safeResult = emptyList.stream().reduce(0, (a, b) -> a + b);
        System.out.println("Result with identity on empty list: " + safeResult);
    }
}
Output
Result without identity on empty list: Optional.empty Result with identity on empty list: 0
📊

Quick Reference

Remember these tips when using reduce:

  • Identity: Starting value, must be neutral (e.g., 0 for sum, 1 for product).
  • Accumulator: Function combining two elements, must be associative.
  • Return type: With identity returns value, without identity returns Optional.
  • Use cases: Summing, multiplying, concatenating, or merging stream elements.

Key Takeaways

Use reduce to combine stream elements into one result with a function.
Provide an identity value to avoid empty results and get a guaranteed output.
Ensure the accumulator function is associative to get correct results.
Without identity, reduce returns an Optional to handle empty streams safely.
Use reduce for simple immutable reductions; use collect for mutable ones.