Clicks know nothing about purchases and vice versa. Index both, take the distinct union of keys, and read each side with a zero default - the pages that appear in only one feed are usually the interesting ones.
record Click(String page, int n) {}
record Buy(String page, int n) {}
var clicks = List.of(new Click("/a", 100), new Click("/b", 40));
var buys = List.of(new Buy("/a", 5), new Buy("/c", 2));
Map<String, Integer> c = clicks.stream().collect(Collectors.toMap(Click::page, Click::n));
Map<String, Integer> b = buys.stream().collect(Collectors.toMap(Buy::page, Buy::n));
Stream.concat(c.keySet().stream(), b.keySet().stream())
.distinct()
.sorted()
.forEach(p -> System.out.println(p + " clicks=" + c.getOrDefault(p, 0)
+ " buys=" + b.getOrDefault(p, 0)));
/a clicks=100 buys=5
/b clicks=40 buys=0
/c clicks=0 buys=2
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