Flatten a List of Lists Using flatMap in Java
Problem
flatMap maps each element to a stream of results and then joins all those streams into one, removing a level of nesting.
Given a list of teams, where each team is a list of member names, produce a single list of every member.
Java Program
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlattenListOfLists {
public static void main(String[] args) {
List<List<String>> teams = Arrays.asList(
Arrays.asList("Ana", "Ben"),
Arrays.asList("Cara"),
Arrays.asList("Dev", "Eli", "Fay"));
List<String> everyone = teams.stream()
.flatMap(List::stream) // each inner list becomes a stream, then they're joined end to end
.collect(Collectors.toList());
System.out.println("Teams: " + teams);
System.out.println("Everyone: " + everyone);
}
}Output
Core Logic
Each inner list can produce its own stream; flatMap takes those per-team streams and lays them end to end as one continuous stream.
- 1
teams.stream()is a stream of lists. - 2
flatMap(List::stream)turns every inner list into a stream of names and concatenates them. - 3
collect(Collectors.toList())gathers the flattened names. - 4The order follows the outer list first, then each inner list.
Key Point: Using map(List::stream) instead would give a Stream<Stream<String>> — a stream of streams — which is exactly the nesting flatMap removes.
Why: Each of the n names across all teams is visited once and copied into the result list.
Key Concepts
Approach 2: Splitting Sentences into Unique Words
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlattenSentencesToWords {
public static void main(String[] args) {
List<String> lines = Arrays.asList("streams are lazy", "streams are composable");
List<String> uniqueWords = lines.stream()
.flatMap(line -> Arrays.stream(line.split(" "))) // one line -> many words
.distinct()
.collect(Collectors.toList());
System.out.println(uniqueWords);
}
}
Output
Core Logic
flatMap isn't limited to nested lists — any element that can be expanded into several values works, such as a sentence into its words.
- 1Each line is split on spaces into an array of words.
- 2
Arrays.stream(...)turns that array into a stream, andflatMapmerges all of them. - 3
distinct()drops words that already appeared.
streams and are appear in both lines but are kept only once.Key Point: This one-to-many expansion is the most common real-world use of flatMap — order lines from orders, tags from posts, words from text.
Why: Every word is processed once, and distinct remembers the u unique words seen so far.
Key Concepts
Interview Questions
What's the difference between map and flatMap?
map produces exactly one result per element. flatMap produces a stream per element and merges those streams into one.
How do you flatten an array of arrays?
Arrays.stream(matrix).flatMapToInt(Arrays::stream).toArray() turns an int[][] into a flat int[].