Stream.concat glues two sources together, but concatenation is not merging - the result is still feed-one-then-feed-two until you sort it on the event time both feeds share.
record Event(String source, int atSeconds, String what) {}
var web = List.of(new Event("web", 3, "view"), new Event("web", 9, "cart"));
var app = List.of(new Event("app", 1, "open"), new Event("app", 7, "search"));
System.out.println("-- concat only --");
Stream.concat(web.stream(), app.stream())
.forEach(e -> System.out.println(e.atSeconds() + "s " + e.source() + " " + e.what()));
System.out.println("-- merged timeline --");
Stream.concat(web.stream(), app.stream())
.sorted(Comparator.comparingInt(Event::atSeconds))
.forEach(e -> System.out.println(e.atSeconds() + "s " + e.source() + " " + e.what()));
-- concat only --
3s web view
9s web cart
1s app open
7s app search
-- merged timeline --
1s app open
3s web view
7s app search
9s web cart
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