flatMap para coleções aninhadas
Achate listas aninhadas, cadeias de Optional e estruturas de arquivos e linhas usando flatMap.
flatMap para coleções aninhadas é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.
O problema das coleções aninhadas
Quando cada elemento de um fluxo é mapeado para outra coleção, map produz um Stream<List<T>>. flatMap mescla os fluxos internos em um único Stream<T> plano.
List<List<Integer>> nested = List.of(List.of(1,2), List.of(3,4), List.of(5));
// With map:
Stream<List<Integer>> s = nested.stream().map(l -> l); // Stream<List<Integer>>
// With flatMap:
Stream<Integer> flat = nested.stream().flatMap(List::stream); // Stream<Integer>
flat.forEach(System.out::println); // 1 2 3 4 5flatMap versus map
map(f) aplica f a cada elemento e envolve o resultado. flatMap(f) aplica f, que retorna um fluxo, e depois concatena todos esses fluxos em um só.
// map: List<String> -> Stream<Stream<Character>>
Stream<Stream<Character>> nested = List.of("hi","bye").stream()
.map(s -> s.chars().mapToObj(c -> (char)c));
// flatMap: List<String> -> Stream<Character>
Stream<Character> flat = List.of("hi","bye").stream()
.flatMap(s -> s.chars().mapToObj(c -> (char)c));Achatar pedidos e itens
Uso clássico: cada pedido tem uma lista de itens. Obtenha um fluxo plano com todos os itens de todos os pedidos.
List<String> allItems = orders.stream()
.flatMap(order -> order.getItems().stream())
.collect(Collectors.toList());
System.out.println(allItems);flatMap com Optional
Use stream() em Optional (Java 9 ou posterior) para convertê-lo em um fluxo com 0 ou 1 elemento. Em seguida, flatMap transforma um Stream<Optional<T>> em um Stream<T>.
List<Optional<String>> maybes = List.of(Optional.of("a"), Optional.empty(), Optional.of("c"));
List<String> values = maybes.stream()
.flatMap(Optional::stream) // Java 9+
.collect(Collectors.toList());
System.out.println(values); // [a, c]Lendo todas as linhas de vários arquivos
flatMap facilita a concatenação de todas as linhas de uma lista de arquivos em um único fluxo, sem laços aninhados.
List<Path> files = List.of(Path.of("a.txt"), Path.of("b.txt"));
List<String> allLines = files.stream()
.flatMap(p -> {
try { return Files.lines(p); }
catch (IOException e) { return Stream.empty(); }
})
.collect(Collectors.toList());Dividindo strings em palavras
Divida cada frase em palavras e achate todas as palavras em um único fluxo para contar a frequência das palavras.
List<String> sentences = List.of("hello world", "java streams rock");
Map<String, Long> freq = sentences.stream()
.flatMap(s -> Arrays.stream(s.split("\\s+")))
.collect(Collectors.groupingBy(w -> w, Collectors.counting()));
System.out.println(freq);flatMap com Map.entrySet
Achate um mapa de categorias para listas de itens em um fluxo com todos os itens.
Map<String, List<String>> catalog = Map.of(
"fruit", List.of("apple","banana"),
"veg", List.of("carrot","pea"));
List<String> all = catalog.values().stream()
.flatMap(List::stream)
.sorted()
.collect(Collectors.toList());
System.out.println(all); // [apple, banana, carrot, pea]Evitando NullPointerException em flatMap
Se a função puder retornar null em vez de um fluxo, use uma verificação de nulo ou retorne Stream.empty() para evitar NullPointerException.
departments.stream()
.flatMap(dept -> dept.getEmployees() == null
? Stream.empty()
: dept.getEmployees().stream())
.forEach(System.out::println);Contando palavras distintas com flatMap
Combine flatMap, distinct e count para um processamento conciso dos dados.
long distinctWords = sentences.stream()
.flatMap(s -> Arrays.stream(s.toLowerCase().split("[^a-z]+")))
.filter(w -> !w.isEmpty())
.distinct()
.count();
System.out.println("Distinct: " + distinctWords);flatMapToInt para fluxos de tipos primitivos
Use flatMapToInt, flatMapToLong e flatMapToDouble para evitar boxing ao achatar fluxos de tipos primitivos.
int totalQuantity = orders.stream()
.flatMapToInt(order -> order.getItems().stream().mapToInt(Item::getQuantity))
.sum();
System.out.println("Total qty: " + totalQuantity);Observação de desempenho
Cada chamada a flatMap adiciona uma camada de fluxo. Para conjuntos de dados muito grandes com muitas coleções internas pequenas, considere abordagens iterativas ou Spliterator para reduzir a sobrecarga da criação de objetos.
Verificação rápida
O que flatMap faz de diferente em relação a map?
Recapitulação
flatMap converte cada elemento em um fluxo e mescla todos os fluxos em um só. Use-o para achatar coleções aninhadas, encadear Optionals, dividir strings e ler vários arquivos. Use flatMapToInt para evitar boxing.
Perguntas Frequentes
A aula “flatMap para coleções aninhadas” é grátis?
Sim — o texto completo de “flatMap para coleções aninhadas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.
O que vou aprender em “flatMap para coleções aninhadas”?
Achate listas aninhadas, cadeias de Optional e estruturas de arquivos e linhas usando flatMap. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Java Academy?
Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “flatMap para coleções aninhadas”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Java Academy?
Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- flatMap para coleções aninhadas
- Streams paralelos: desempenho e armadilhas
- Spliterator: divisão para paralelismo
- Streams infinitos com iterate e generate