Aggregates live at a grain. flatMap is how you move from the order grain down to the line grain, which is the only level where a revenue sum is correct.
record Line(String sku, int qty, double price) {}
record Order(String ref, List<Line> lines) {}
var orders = List.of(
new Order("A-1", List.of(new Line("S1", 2, 50.0), new Line("S2", 1, 150.0))),
new Order("A-2", List.of(new Line("S1", 1, 50.0))));
double revenue = orders.stream()
.flatMap(o -> o.lines().stream())
.mapToDouble(l -> l.qty() * l.price())
.sum();
Map<String, Integer> unitsBySku = orders.stream()
.flatMap(o -> o.lines().stream())
.collect(Collectors.groupingBy(Line::sku, TreeMap::new, Collectors.summingInt(Line::qty)));
System.out.println("revenue: " + revenue);
System.out.println("units : " + unitsBySku);
revenue: 300.0
units : {S1=3, S2=1}
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