Two hops - line to order, order to customer - do not need two passes. Join on the way into groupingBy and the classifier does the hop for you.
record Order(String ref, String customer) {}
record Line(String orderRef, String sku, double amount) {}
var orders = List.of(new Order("A-1", "Ava"), new Order("A-2", "Ben"), new Order("A-3", "Ava"));
var lines = List.of(new Line("A-1", "S1", 100.0), new Line("A-1", "S2", 150.0),
new Line("A-2", "S1", 50.0), new Line("A-3", "S3", 40.0));
Map<String, String> customerOf = orders.stream()
.collect(Collectors.toMap(Order::ref, Order::customer));
Map<String, Double> byCustomer = lines.stream()
.collect(Collectors.groupingBy(l -> customerOf.get(l.orderRef()),
TreeMap::new,
Collectors.summingDouble(Line::amount)));
System.out.println(byCustomer);
{Ava=290.0, Ben=50.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-09-20