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: Combines elements using thereduce(BinaryOperator<T> accumulator) accumulatorfunction, returns anOptionalbecause the stream might be empty.T reduce(T identity, BinaryOperator<T> accumulator): Uses anidentityvalue 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
reducewithcollectfor 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.