Functional Programming & Streams

Collectors

collect performs mutable reduction through a Collector recipe. Collectors covers containers (toList, toSet, toMap), strings (joining), statistics, and — its real power — groupingBy/partitioningBy with downstream collectors.
  • toMap(keyFn, valueFn) throws on duplicate keys — pass a merge function when keys can repeat
  • groupingBy(classifier)Map<K, List<T>>; add a downstream collector to aggregate per group
  • partitioningBy(predicate)Map<Boolean, …> with exactly two entries
  • Downstream combinators: counting, summingInt, mapping, filtering, collectingAndThen
  • joining(", ", "[", "]") for delimited strings
The everyday set
Map<String, Employee> byId = staff.stream()
        .collect(toMap(Employee::id, e -> e));                 // throws on dup ids — good!

Map<String, Double> highestPayByDept = staff.stream()
        .collect(toMap(Employee::dept, Employee::salary, Double::max));  // merge fn

String csv = names.stream().collect(joining(", "));
IntSummaryStatistics stats = words.stream().collect(summarizingInt(String::length));
// stats.getMax(), getMin(), getAverage(), getCount(), getSum()
groupingBy with downstreams — SQL GROUP BY in the language
Map<String, List<Employee>> byDept = staff.stream()
        .collect(groupingBy(Employee::dept));

Map<String, Long> headcount = staff.stream()
        .collect(groupingBy(Employee::dept, counting()));

Map<String, Double> payroll = staff.stream()
        .collect(groupingBy(Employee::dept, summingDouble(Employee::salary)));

Map<String, Set<String>> namesByDept = staff.stream()
        .collect(groupingBy(Employee::dept,
                 mapping(Employee::name, toCollection(TreeSet::new))));

Downstream collectors nest arbitrarily — groupingBy(f, groupingBy(g, counting())) builds two-level maps. collectingAndThen(toList(), List::copyOf) post-processes a result (here: seal it immutable). teeing(c1, c2, merger) (Java 12) runs two collectors over one pass and merges their results.

Sources
  • Core Java, Volume II: Advanced Features (13th ed.)Ch. 1.8–1.11 — Collecting Results; Grouping
  • Effective Java (3rd ed.)Item 46