Streams: filtering collector keeps empty groups alive

Calling filter() before groupingBy drops keys entirely. Collectors.filtering filters inside each group, so every key still appears - usually what a report needs.

Code
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);
Output
filter() first       : {north=1}
Collectors.filtering : {north=1, south=0}
Advertisement

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