The full picture
record Order(String region, String product, BigDecimal total) {}
// revenue per region, per product — ONE pass
Map<String, Map<String, BigDecimal>> revenue = orders.stream()
.collect(groupingBy(Order::region,
groupingBy(Order::product,
reducing(BigDecimal.ZERO, Order::total, BigDecimal::add))));
// top order per region — no sorting the whole stream
Map<String, Optional<Order>> top = orders.stream()
.collect(groupingBy(Order::region,
maxBy(comparing(Order::total))));
// toMap: ALWAYS decide the merge policy
Map<String, Order> byId = orders.stream()
.collect(toMap(Order::product, o -> o, (a, b) -> a.total().compareTo(b.total()) >= 0 ? a : b));teeing(c1, c2, merger)(Java 12) runs two collectors in one pass — e.g., min and max together.collectingAndThen(toList(), List::copyOf)finishes with an immutable result.- Custom collector: implement supplier/accumulator/combiner (+ characteristics
CONCURRENT,UNORDERED,IDENTITY_FINISH); the combiner must be associative or parallel results silently corrupt. mapMulti(Java 16) as a lower-allocation alternative toflatMapfor 0..n expansions.