Careeroza
Collectors and groupingBy
Useful Collectors
| Collector | Result |
|---|---|
toList(), toSet(), toCollection(TreeSet::new) | collections |
toMap(keyFn, valueFn, mergeFn) | Map (merge function handles duplicate keys) |
joining(", ", "[", "]") | String |
groupingBy(classifier, downstream) | Map<K, List<T>> or with a downstream collector |
partitioningBy(predicate) | Map<Boolean, List<T>> |
counting(), summingInt, averagingDouble | numbers (used as downstream) |
mapping, filtering, flatMapping | transform inside a group |
summarizingInt | count, sum, min, average, max in one go |
teeing(c1, c2, merger) (Java 12) | two collectors combined |
Grouping Orders
Example
groupingBy returns a HashMap by default; pass TreeMap::new when you want sorted keys.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Order> orders = List.of(
new Order("Mumbai", "Electronics", 25000), new Order("Delhi", "Fashion", 3200),
new Order("Mumbai", "Fashion", 1800), new Order("Pune", "Electronics", 15000),
new Order("Delhi", "Electronics", 42000), new Order("Mumbai", "Grocery", 900));
Map<String, Long> countByCity = orders.stream()
.collect(Collectors.groupingBy(Order::city, TreeMap::new, Collectors.counting()));
System.out.println("Orders per city: " + countByCity);
Map<String, Integer> revenueByCategory = orders.stream()
.collect(Collectors.groupingBy(Order::category, TreeMap::new, Collectors.summingInt(Order::amount)));
System.out.println("Revenue per category: " + revenueByCategory);
Map<String, List<String>> categoriesByCity = orders.stream()
.collect(Collectors.groupingBy(Order::city, TreeMap::new,
Collectors.mapping(Order::category, Collectors.toList())));
System.out.println("Categories per city: " + categoriesByCity);
Map<Boolean, Long> bigOrders = orders.stream()
.collect(Collectors.partitioningBy(o -> o.amount() >= 10000, Collectors.counting()));
System.out.println("Big vs small: " + bigOrders);
IntSummaryStatistics stats = orders.stream().collect(Collectors.summarizingInt(Order::amount));
System.out.println("Stats: min=" + stats.getMin() + " max=" + stats.getMax() + " avg=" + stats.getAverage());
}
}
record Order(String city, String category, int amount) {}Output
Orders per city: {Delhi=2, Mumbai=3, Pune=1}
Revenue per category: {Electronics=82000, Fashion=5000, Grocery=900}
Categories per city: {Delhi=[Fashion, Electronics], Mumbai=[Electronics, Fashion, Grocery], Pune=[Electronics]}
Big vs small: {false=3, true=3}
Stats: min=900 max=42000 avg=14650.0toMap and joining
Example
toMap throws IllegalStateException on duplicate keys unless you pass a merge function.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("java", "kotlin", "jdbc", "spring", "kafka");
Map<Character, String> byFirstLetter = words.stream()
.collect(Collectors.toMap(w -> w.charAt(0), w -> w, (a, b) -> a + "|" + b, TreeMap::new));
System.out.println(byFirstLetter);
String csv = words.stream().map(String::toUpperCase).collect(Collectors.joining(", ", "[", "]"));
System.out.println(csv);
double avgLen = words.stream().collect(Collectors.averagingInt(String::length));
System.out.println("Average length: " + avgLen);
}
}Output
{j=java|jdbc, k=kotlin|kafka, s=spring}
[JAVA, KOTLIN, JDBC, SPRING, KAFKA]
Average length: 5.0