mapMulti: flatMap Without the Streams

Streams · lesson 24 of 42 · 3 min read

Push zero, one or many results downstream per element, with no inner Stream allocated.

Open this lesson in the learning hub

Key points

  • mapMulti (Java 16+) hands your lambda a push function. Call it as often as you like, including never.
  • flatMap has to allocate a Stream for every element. mapMulti allocates 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.