The concurrent collector writes into one ConcurrentMap instead of merging per-thread maps, which is faster in a parallel stream - at the cost of encounter order.
var words = IntStream.rangeClosed(1, 1000).mapToObj(i -> "w" + (i % 4)).toList();
ConcurrentMap<String, Long> counts = words.parallelStream()
.collect(Collectors.groupingByConcurrent(w -> w, Collectors.counting()));
new TreeMap<>(counts).forEach((k, v) -> System.out.println(k + " -> " + v));
w0 -> 250
w1 -> 250
w2 -> 250
w3 -> 250
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-07-30