Calling filter() before groupingBy drops keys entirely. Collectors.filtering filters inside each group, so every key still appears - usually what a report needs.
record Sale(String region, int amount) {}
var sales = List.of(new Sale("north", 500), new Sale("north", 50), new Sale("south", 20));
var filterFirst = sales.stream().filter(x -> x.amount() >= 100)
.collect(Collectors.groupingBy(Sale::region, TreeMap::new, Collectors.counting()));
System.out.println("filter() first : " + filterFirst);
var filterInside = sales.stream()
.collect(Collectors.groupingBy(Sale::region, TreeMap::new,
Collectors.filtering(x -> x.amount() >= 100, Collectors.counting())));
System.out.println("Collectors.filtering : " + filterInside);
filter() first : {north=1}
Collectors.filtering : {north=1, south=0}
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-07-30