🧠 Tópico: Use flatMap() methods in the Stream API

🔹 Objetivo:

Entender como o flatMap() transforma uma estrutura de coleções aninhadas (como List<List<X>>) em uma única stream plana.


Conceito

O método flatMap():

  • Recebe uma função que retorna um Stream.
  • “Achata” (flatten) várias streams em uma única stream contínua.
  • Evita streams aninhadas dentro de streams.

🔹 Exemplo prático:

List<List<String>> listas = List.of(
List.of("a", "b"),
List.of("c", "d"),
List.of("e")
);

List<String> resultado = listas.stream()
.flatMap(List::stream)
.collect(Collectors.toList());

System.out.println(resultado); // [a, b, c, d, e]

🗣️ Sem flatMap, você teria uma Stream<List<String>>. Com ele, obtemos uma Stream<String> direto.


🔹 Comparação com map()

listas.stream().map(List::stream)
// Stream<Stream<String>>

listas.stream().flatMap(List::stream)
// Stream<String>

🔹 Aplicação com objetos

class Pessoa {
String nome;
List<String> telefones;

Pessoa(String nome, List<String> telefones) {
this.nome = nome;
this.telefones = telefones;
}
}

List<Pessoa> pessoas = List.of(
new Pessoa("Ana", List.of("111", "222")),
new Pessoa("Bia", List.of("333"))
);

List<String> todosTelefones = pessoas.stream()
.flatMap(p -> p.telefones.stream())
.collect(Collectors.toList());

System.out.println(todosTelefones); // [111, 222, 333]

🔹 Versões primitivas

  • flatMapToInt()
  • flatMapToLong()
  • flatMapToDouble()

Exemplo:

List<String> numeros = List.of("1,2", "3,4");

IntStream stream = numeros.stream()
.flatMapToInt(s -> Arrays.stream(s.split(",")).mapToInt(Integer::parseInt));

stream.forEach(System.out::println);

// 1 2 3 4

🧪 Quiz: 5 Questões Rápidas

1. O que flatMap() espera como retorno da função passada?

A) Qualquer objeto
B) Uma Collection
C) Um Stream
D) Um valor primitivo


2. Dado List<List<Integer>>, qual método evita Stream<Stream<Integer>>?

A) map()
B) forEach()
C) filter()
D) flatMap()


3. O que flatMapToInt() retorna?

A) IntStream
B) Stream<Integer>
C) List<Integer>
D) Optional<Integer>


4. O que esse código imprime?

Stream.of("a,b", "c,d")
.flatMap(s -> Arrays.stream(s.split(",")))
.forEach(System.out::print);

A) abcd
B) [a, b, c, d]
C) a,b,c,d
D) acbd


5. Quando devo preferir flatMapToInt() em vez de flatMap()?

A) Quando preciso de números em uma lista
B) Quando o stream de saída deve ser de primitivos
C) Quando quero ordenar strings
D) Quando preciso de Optional<Integer>


Gabarito

  1. C – Espera um Stream<T>.
  2. DflatMap() achata o nível de profundidade.
  3. A – Retorna um IntStream.
  4. A – Divide as strings e imprime sem separação.
  5. BflatMapToInt() é para performance com primitivos.