ComparisonDifficulty: Intermediate1 min

map Against flatMap

Both take a function and apply it to every element. The difference is what they do with the result, and the symptom of choosing wrongly is a type you did not want.

What each one does with the value your function returns
Compared onmapflatMap
Your function returnsA valueA stream
The result isA stream of those valuesOne stream with every element of every returned stream
Element countExactly the sameAny number, including zero
java
Stream<List<Invoice>> nested = customers.stream().map(Customer::invoices);

Stream<Invoice> flat = customers.stream().flatMap(c -> c.invoices().stream());
line 1 gives a stream of lists; line 3 gives a stream of invoices

The decision rule. If your function returns one thing per element, map. If it returns several — a list, a stream, an Optional — and you want them all in one flat stream, flatMap.

The symptom is in the type. A Stream<List<X>> or a Stream<Stream<X>> in the middle of a pipeline is almost always a map that should have been a flatMap, and the compiler will tell you about it at the next step.