SyntaxStudy
Sign Up
Java Stream reduce and Advanced Collectors
Java Beginner 1 min read

Stream reduce and Advanced Collectors

reduce() is a terminal operation that combines all elements of a stream into a single result by repeatedly applying a BinaryOperator. It takes an identity value (the starting accumulator) and the combining function. For example, reduce(0, Integer::sum) computes the sum of all integers. For non-associative operations or when the identity is not obvious, you can use the single-argument form which returns an Optional. Beyond toList() and groupingBy(), the Collectors class provides counting(), summingInt(), averagingDouble(), summarizingInt() (returns a summary with count, sum, min, max, average), and toUnmodifiableList(). Collectors.partitioningBy() is a specialisation of groupingBy that splits elements into two groups (true/false) based on a Predicate, returning a Map>. IntStream, LongStream, and DoubleStream are primitive specialisations that avoid boxing overhead and add domain-specific methods like sum(), average(), min(), max(), and range(). You convert to a primitive stream with mapToInt(), mapToLong(), or mapToDouble(), and back to an object stream with boxed() or mapToObj(). Using primitive streams for numeric work is both more efficient and more expressive.
Example
import java.util.*;
import java.util.stream.*;

public class StreamReduceDemo {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // reduce: sum
        int sum = numbers.stream()
            .reduce(0, Integer::sum);
        System.out.println("Sum: " + sum);

        // reduce: product
        long product = numbers.stream()
            .reduce(1, (a, b) -> a * b);
        System.out.println("Product: " + product);

        // IntStream — no boxing
        IntSummaryStatistics stats = numbers.stream()
            .mapToInt(Integer::intValue)
            .summaryStatistics();
        System.out.printf("Count=%d, Sum=%d, Min=%d, Max=%d, Avg=%.1f%n",
            stats.getCount(), stats.getSum(),
            stats.getMin(),   stats.getMax(), stats.getAverage());

        // partitioningBy
        Map<Boolean, List<Integer>> evenOdd = numbers.stream()
            .collect(Collectors.partitioningBy(n -> n % 2 == 0));
        System.out.println("Even: " + evenOdd.get(true));
        System.out.println("Odd:  " + evenOdd.get(false));

        // IntStream.range
        int sumTo100 = IntStream.rangeClosed(1, 100).sum();
        System.out.println("Sum 1..100 = " + sumTo100);

        // flatMap: flatten nested lists
        List<List<Integer>> nested = List.of(List.of(1,2), List.of(3,4), List.of(5));
        List<Integer> flat = nested.stream()
            .flatMap(Collection::stream)
            .collect(Collectors.toList());
        System.out.println("Flattened: " + flat);
    }
}