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 =

{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 =
    .collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toSet()));

{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 =;

{Fruit=[Orange, Apple], Vegetable=[Potato, Carrot], Meat=[Beef, Pork]}

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 =
        .collect(groupingBy(Product::getType, counting()));

{Fruit=2, Vegetable=2, Meat=2}

Or if we cant to calculate the average price per category, we could do

Map<String, Double> productsPriceByType =
    .collect(groupingBy(Product::getType, averagingInt(Product::getPrice)));

{Fruit=5.0, Vegetable=3.0, Meat=9.0}