Multi-stream: top N per group with collectingAndThen

groupingBy hands each group to a downstream collector; collectingAndThen lets that downstream finish with a sort and a limit. One pass builds the groups, and each group is ranked as it closes.

Code
record Sale(String region, String rep, double amount) {}

var sales = List.of(new Sale("east", "Ava", 300.0), new Sale("east", "Ben", 500.0),
                    new Sale("east", "Cara", 100.0), new Sale("west", "Dan", 250.0),
                    new Sale("west", "Eve", 900.0), new Sale("west", "Fay", 400.0));

Map<String, List<String>> top2 = sales.stream().collect(Collectors.groupingBy(Sale::region, TreeMap::new,
        Collectors.collectingAndThen(Collectors.toList(), group -> group.stream()
                .sorted(Comparator.comparingDouble(Sale::amount).reversed())
                .limit(2)
                .map(s -> s.rep() + "(" + s.amount() + ")")
                .toList())));

top2.forEach((region, reps) -> System.out.println(region + ": " + reps));
Output
east: [Ben(500.0), Ava(300.0)]
west: [Eve(900.0), Fay(400.0)]
Advertisement
More in JAVA

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-09-20

© Java Coding Hub · About · Contact · Privacy · Terms