Multi-stream: join on a composite key using a record

Real joins are rarely on one column. A record gives you equals and hashCode for free, so a two-field key works as a Map key immediately - no string concatenation that breaks the first time a value contains the separator.

Code
record Key(String region, String sku) {}
record Stock(String region, String sku, int onHand) {}
record Demand(String region, String sku, int wanted) {}

var stock = List.of(new Stock("east", "S1", 10), new Stock("west", "S1", 2));
var demand = List.of(new Demand("east", "S1", 4), new Demand("west", "S1", 5),
                     new Demand("east", "S2", 1));

Map<Key, Integer> onHand = stock.stream()
        .collect(Collectors.toMap(s -> new Key(s.region(), s.sku()), Stock::onHand));

demand.stream()
      .sorted(Comparator.comparing(Demand::region).thenComparing(Demand::sku))
      .forEach(d -> {
          int have = onHand.getOrDefault(new Key(d.region(), d.sku()), 0);
          System.out.println(d.region() + "/" + d.sku() + " want " + d.wanted() + " have " + have
                  + (have >= d.wanted() ? "  OK" : "  SHORT " + (d.wanted() - have)));
      });
Output
east/S1 want 4 have 10  OK
east/S2 want 1 have 0  SHORT 1
west/S1 want 5 have 2  SHORT 3
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