The building block of every multi-list pipeline. Index the smaller list once into a Map, then stream the larger one and look each row up - O(n+m) instead of the O(n*m) a nested filter costs.
record Customer(int id, String name, String city) {}
record Order(String ref, int customerId, double amount) {}
var customers = List.of(new Customer(1, "Ava", "Pune"),
new Customer(2, "Ben", "Kochi"),
new Customer(3, "Cara", "Delhi"));
var orders = List.of(new Order("A-1", 1, 250.0),
new Order("A-2", 3, 90.0),
new Order("A-3", 1, 40.0));
// Build the index ONCE, outside the pipeline.
Map<Integer, Customer> byId = customers.stream()
.collect(Collectors.toMap(Customer::id, c -> c));
orders.stream()
.map(o -> byId.get(o.customerId()).name() + " " + o.ref() + " " + o.amount())
.forEach(System.out::println);
Ava A-1 250.0
Cara A-2 90.0
Ava A-3 40.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