0Pricing
Java Academy · Aula

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 5

flatMap 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

  1. flatMap para coleções aninhadas
  2. Streams paralelos: desempenho e armadilhas
  3. Spliterator: divisão para paralelismo
  4. Streams infinitos com iterate e generate
← Voltar para Java Academy