Java Stream flatMap
last modified May 24, 2025
This article demonstrates how to use the Java Stream flatMap method to transform and flatten nested data structures.
flatMap is an intermediate stream operation that maps each element to a stream and then flattens these streams into a single stream. It's particularly useful when working with nested collections or when each element can be transformed to multiple elements.
Basic flatMap syntax
The method signature for flatMap
is:
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
The mapper function takes an element of type T and returns a Stream of R. The flatMap operation then concatenates all these streams into a single stream.
Flattening nested collections
The most common use case for flatMap is flattening nested collections.
void main() { List<List<String>> nestedLists = List.of( List.of("a", "b", "c"), List.of("d", "e"), List.of("f", "g", "h", "i") ); Stream<String> flattened = nestedLists.stream() .flatMap(List::stream); flattened.forEach(System.out::println); }
This example takes a list of lists and flattens it into a single stream of strings. The List::stream method reference converts each inner list to a stream, and flatMap combines them.
Transforming and flattening
flatMap can both transform elements and flatten the results.
void main() { List<Integer> numbers = List.of(1, 2, 3, 4); Stream<Integer> doubled = numbers.stream() .flatMap(n -> Stream.of(n, n * 2)); doubled.forEach(System.out::println); }
This example takes each number and maps it to a stream containing the original number and its double. The flatMap operation then combines all these streams.
Handling optional values
flatMap is useful for filtering out empty Optionals while extracting values.
void main() { List<Optional<String>> options = List.of( Optional.of("apple"), Optional.empty(), Optional.of("banana"), Optional.empty(), Optional.of("cherry") ); Stream<String> fruits = options.stream() .flatMap(Optional::stream); fruits.forEach(System.out::println); }
This example filters out empty Optionals and extracts the values from present
ones. The Optional::stream
method converts an Optional
to a stream of 0 or 1 elements.
Splitting strings into words
flatMap can be used to split strings and combine all words into one stream.
void main() { List<String> sentences = List.of( "Hello there", "Java streams are powerful", "flatMap is useful" ); Stream<String> words = sentences.stream() .flatMap(s -> Stream.of(s.split(" "))); words.forEach(System.out::println); }
This example splits each sentence into words and combines all words from all sentences into a single stream. The lambda splits each string by spaces.
$ java Main.java Hello there Java streams are powerful flatMap is useful
Working with nested objects
flatMap is useful for extracting nested collections from objects.
record Order(String id, List<String> items) { } void main() { List<Order> orders = List.of( new Order("001", List.of("Shirt", "Pants")), new Order("002", List.of("Shoes", "Socks", "Hat")), new Order("003", List.of("Jacket")) ); Stream<String> allItems = orders.stream() .flatMap(order -> order.items().stream()); allItems.forEach(System.out::println); }
This example extracts all items from all orders into a single stream. Each Order's items are converted to a stream and then flattened.
$ java Main.java Shirt Pants Shoes Socks Hat Jacket
Combining multiple streams
flatpMap
can combine elements from multiple sources.
void main() { Stream<String> stream1 = Stream.of("A", "B", "C"); Stream<String> stream2 = Stream.of("X", "Y", "Z"); Stream<Stream<String>> nested = Stream.of(stream1, stream2); Stream<String> combined = nested.flatMap(s -> s); combined.forEach(System.out::println); }
This example combines two separate streams into one using flatMap
.
Note that once a stream is consumed (like in the flatMap operation), it can't be
reused.
Generating Cartesian products
flatMap can be used to generate Cartesian products of collections.
void main() { List<String> colors = List.of("Red", "Green", "Blue"); List<String> sizes = List.of("S", "M", "L"); Stream<String> products = colors.stream() .flatMap(color -> sizes.stream() .map(size -> color + " " + size) ); products.forEach(System.out::println); }
This example generates all possible combinations of colors and sizes. Each color is paired with each size using nested flatMap and map operations.
$ java Main.java Red S Red M Red L Green S Green M Green L Blue S Blue M Blue L
flatMap with primitive streams
You can use flatMapToInt
, flatMapToDouble
, or
flatMapToLong
to flatten and process collections of numbers. For
example, you can convert a list of strings representing numbers into a single
IntStream
.
void main() { List<String> numberStrings = List.of("1,2,3", "4,5", "6"); IntStream numbers = numberStrings.stream() .flatMapToInt(s -> Arrays.stream(s.split(",")).mapToInt(Integer::parseInt)); numbers.forEach(System.out::println); }
This example splits each string by commas, parses the numbers, and flattens them
into a single IntStream
.
Parsing and flattening CSV data
flatMap can be used to parse a list of CSV strings, extract fields, and flatten them into a single stream for further processing.
record User(String firstName, String lastName, int age) { } void main() { List<String> csvRows = List.of("John,Doe,30", "Jane,Smith,25", "Bob,Johnson,40"); Stream<User> users = csvRows.stream() .map(row -> row.split(",")) // Split row .map(fields -> new User(fields[0], fields[1], Integer.parseInt(fields[2]))); // Convert to User users.forEach(System.out::println); }
The example demonstrates how to parse CSV data, where each row is split into
fields, and then each field is used to create a User
object. The
flatMap method is not explicitly used here, but it can be applied if you want to
flatten nested structures or combine multiple streams of users.
Source
Java Stream flatMap documentation
In this article we have explored the Java Stream flatMap
method.
It's a powerful tool for working with nested data structures, combining multiple
streams, and transforming elements while flattening the results.
Author
List all Java tutorials.