CodeBlanks Logo Icon CodeBlanks

collect groupingBy

Learn grouping with Collectors.groupingBy.

Grouping a stream

To terminate a stream you use the collect method. The Collectors class offers ready-made collectors for this. The most common one is groupingBy: it splits elements into groups by a classifier function.

Example: products.stream().collect(Collectors.groupingBy(Product::category)). Each product lands in a group based on its category; the result is a Map<String, List<Product>>. The keys are categories, the values are the lists of products in each category.

groupingBy output and ordered map

By default groupingBy returns a HashMap; the order of keys is undefined. To make the output deterministic you use the three-argument overload: classifier, map supplier and a downstream collector.

Example: Collectors.groupingBy(Product::category, TreeMap::new, Collectors.toList()). TreeMap::new keeps keys in natural order; the forEach output is then identical on every run. If you swap the downstream for Collectors.counting() you get a count per group.

Practice Group products by category

Create a list of three products (record Product(String name, String category, double price)). Group the stream by category with Collectors.groupingBy; pass TreeMap::new and Collectors.toList() for ordered output. Then use forEach to print each category's count with System.out.println.

Starter code

Main.java
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

record Product(String name, String category, double price) {}

// Group the products by category
// Use Collectors.groupingBy with a TreeMap supplier
// Print each category's count with forEach

Sample solution

Main.java
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;

record Product(String name, String category, double price) {}

public class GroupByCategory {
    public static void main(String[] args) {
        List<Product> products = List.of(
            new Product("Pen", "Office", 12.5),
            new Product("Notebook", "Office", 25.0),
            new Product("Bread", "Grocery", 5.0)
        );
        Map<String, List<Product>> byCategory = products.stream()
            .collect(Collectors.groupingBy(Product::category, TreeMap::new, Collectors.toList()));
        byCategory.forEach((k, v) -> System.out.println(k + ": " + v.size()));
    }
}

Expected output

Office: 2
Grocery: 1

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Which collector splits a stream into groups by a classifier function?

  • Collectors.groupingBy(...) Correct answer
  • Collectors.toList(...)
  • Stream.of(...)
  • Optional.of(...)

Explanation: groupingBy groups elements by the classifier.

2 Complete the groupingBy call

Question
Map<String, List<Product>> byCat = products.stream()
    .collect(Collectors.groupingBy(____));
Answer
Map<String, List<Product>> byCat = products.stream()
    .collect(Collectors.groupingBy(Product::category));

Explanation: Product::category is a method reference and works as classifier.

3 Match the groupingBy concepts

Term Meaning
groupingBy Groups by a key
classifier Classifier function
collect Terminal method
TreeMap::new Ordered map supplier

All lessons in Advanced