Fork/join and parallel streams question 107 of 180 senior
What does Collectors.toConcurrentMap change, and when is groupingByConcurrent actually used?
- They are the only collectors that work in parallel
- Correct: They let all threads accumulate into one concurrent container instead of merging per-thread maps, which only helps when the collector is unordered and the stream is parallel
- They make the stream parallel automatically
- They preserve encounter order
An ordinary groupingBy in a parallel stream gives each thread its own map and merges them at the end,
which allocates and copies. The concurrent versions declare the CONCURRENT characteristic, so the
framework lets every thread write into a single ConcurrentHashMap instead.
That is faster only when merging was actually expensive, and it requires the collector to be
UNORDERED too, otherwise the framework falls back to merging to preserve encounter order. Since the
result of a concurrent collector is in unspecified order anyway, using one on a stream where order
matters is a correctness bug rather than an optimisation.
In practice: profile first. The sequential collector plus merge wins more often than people expect.
Quiz yourself on Fork/join and parallel streams Suggest a correction