Java 8 streams collector groupingBy
Suppose we have a List of strings and want to group them by length.
We can use Collectors.groupingBy()
for this task.
List persons = Arrays.asList("Bob", "Natali", "Alice", "Tom");
Map<Integer, List> map = persons.stream()
.collect(Collectors.groupingBy(String::length));
System.out.println(map);
//output
{3=[Bob, Tom], 5=[Alice], 6=[Natali]}
If we want to collect into Set
or have sorted order, we can use overloaded methods of groupingBy
List persons = Arrays.asList("Bob", "Natali", "Alice", "Tom");
Map<Integer, Set> map = persons.stream()
.collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toSet()));
System.out.println(map);
//output
{3=[Tom, Bob], 5=[Alice], 6=[Natali]}
Let’s see another examples of groupingBy
. Say we have a store and want to categorize the products by their type
Map<String, List> productsByType = store.stream().collect(groupingBy(Product::getType));
//output
{Fruit=[Orange, Apple], Vegetable=[Potato, Carrot], Meat=[Beef, Pork]}
[addToAppearHere]
We can pass groupingBy
other collectors as a second parameter. For example if we want to count the number of products per category, we could do
Map<String, Long> productsByType = store.stream()
.collect(groupingBy(Product::getType, counting()));
//output
{Fruit=2, Vegetable=2, Meat=2}
Or if we cant to calculate the average price per category, we could do
Map<String, Double> productsPriceByType = store.stream()
.collect(groupingBy(Product::getType, averagingInt(Product::getPrice)));
//output
{Fruit=5.0, Vegetable=3.0, Meat=9.0}