Stream.reduce() in Java 8
Fast recall
Quick revision
Core answer
reduce() is a terminal reduction that combines elements with an associative function. The overload without an identity returns Optional; an overload with a valid identity returns T. Use it for immutable value reductions such as a sum or maximum. Use collect() for mutable result containers such as lists or string builders.Understanding of reduction operations and functional programming concepts—reduce is more fundamental and flexible than sum or count.
Not understanding the identity value parameter and when to use the Optional-returning version versus the version that takes an identity.
Explain both reduce() overloads—the one with identity that returns T and the one without identity that returns Optional—and show when each is appropriate.
Interview-ready guide
Interview answer
Reduce is the fundamental aggregation operation in streams.
It takes all your elements and combines them into a single value by repeatedly applying a binary function. Imagine you're summing numbers—you take the first two, add them, then take that result and add the third, and so on until you have one final sum. That's reduce.
There are two main versions. The first takes an identity value and a binary operator, and it always returns a result. The identity is your starting value—like zero for sum or one for multiplication.
The second version doesn't take an identity and returns an Optional, which is what you want when an empty stream has no meaningful result, like finding the maximum value.
A common use case is calculating totals. Say you have orders and want total revenue—you'd map to amounts, then reduce with identity zero and addition. The key thing about reduce is the operation needs to be associative, meaning the order you group operations doesn't matter.
This is important for parallel streams. One pitfall freshers hit is choosing the wrong identity or calling dot get on the Optional without checking if it's present. For simple cases like sum, use the specialized methods—they're clearer.
But reduce gives you the flexibility to implement any custom aggregation.
Stream.reduce() in Java 8
Direct Answer
reduce() is a terminal reduction that combines elements with an associative function. The overload without an identity returns Optional<T>; an overload with a valid identity returns T. Use it for immutable value reductions such as a sum or maximum. Use collect() for mutable result containers such as lists or string builders.
Code Example
import java.util.List;
import java.util.Optional;
record Order(long id, long amountCents, int itemCount) {}
class OrderAnalytics {
long totalRevenueCents(List<Order> orders) {
return orders.stream()
.map(Order::amountCents)
.reduce(0L, Long::sum);
}
Optional<Order> largestOrder(List<Order> orders) {
return orders.stream().reduce((left, right) ->
left.amountCents() >= right.amountCents() ? left : right);
}
int totalItemCount(List<Order> orders) {
return orders.stream().map(Order::itemCount).reduce(0, Integer::sum);
}
String summary(List<Order> orders) {
return orders.stream()
.map(order -> String.format("#%d: %d cents",
order.id(), order.amountCents()))
.reduce((left, right) -> left + ", " + right)
.orElse("");
}
}
Using integer minor units keeps the addition associative within the chosen range. Floating-point addition can change slightly when grouping changes, so a parallel floating-point sum needs an explicit accuracy policy.
Common Mistakes & Pitfalls
- Wrong identity: the contract requires
operator(identity, x)to equalx; do not use a convenient starting value that changes each partition. - Ignoring the empty case: the no-identity overload returns
Optional.empty()for an empty stream; handle that outcome explicitly. - Non-associative operator: subtraction or position-dependent formatting can change when grouping changes.
- Mutating a container in reduce: use
collectfor lists, maps, and builders so partial results can be combined correctly.
Check your understanding
Answer these without looking back at the article.
- What is the identity element for reduce()?
- Why does reduce() without identity return Optional?
- What is the difference between reduce() and collect()?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.