mapMulti: flatMap Without the Streams
Push zero, one or many results downstream per element, with no inner Stream allocated.
Open this lesson in the learning hubKey points
mapMulti(Java 16+) hands your lambda a push function. Call it as often as you like, including never.flatMaphas to allocate a Stream for every element.mapMultiallocates nothing extra, which shows up in hot loops.- The result type cannot be inferred from the lambda, so write it explicitly:
stream.<String>mapMulti(...). - Primitive versions exist too:
mapMultiToInt,mapMultiToLong,mapMultiToDouble. - Prefer flatMap for readability. Reach for mapMulti when each element yields few results and the pipeline is hot.
Example
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<String> rows = List.of("a,b", "c", "");
// mapMulti hands you a push function. Call it zero, one, or many times.
List<String> viaMulti = rows.stream()
.<String>mapMulti((row, push) -> {
for (String part : row.split(",")) {
if (!part.isEmpty()) {
push.accept(part);
}
}
})
.toList();
// flatMap gets the same answer but allocates a Stream for every element.
List<String> viaFlatMap = rows.stream()
.flatMap(row -> Arrays.stream(row.split(",")).filter(p -> !p.isEmpty()))
.toList();
System.out.println("mapMulti : " + viaMulti);
System.out.println("flatMap : " + viaFlatMap);
System.out.println("same : " + viaMulti.equals(viaFlatMap));
// Primitive variants push straight into an IntStream, so nothing is boxed.
int total = Stream.of(1, 2, 3)
.mapMultiToInt((n, push) -> {
push.accept(n);
push.accept(n * 10);
})
.sum();
System.out.println("total : " + total);
}
}
mapMulti is flatMap that pushes instead of allocating.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.