8.9 FlatMap – DEV Community

1. Introdução ao flatMap
- Objetivo: “Achatar” (flatten) Streams aninhados em um único Stream (ex: Stream> → Stream).
- Aplicação: Útil para processar coleções de coleções, arquivos com múltiplas linhas, ou estruturas hierárquicas.
2. Exemplo Prático com Arquivos
Problema:
Usar map com Files.lines gera um Stream>, não desejado.
Solução com flatMap:
Stream linhas = Files.list(Paths.get("./caminho/do/diretório"))
.filter(p -> p.toString().endsWith(".java"))
.flatMap(p -> lines(p)); // Converte Stream> → Stream
Resultado: Todas as linhas de todos os arquivos .java em um único Stream.
3. Exemplo com Caracteres (flatMapToInt)
Objetivo: Obter todos os caracteres (como int) de todas as linhas dos arquivos.
Código:
IntStream caracteres = Files.list(Paths.get("./caminho/do/diretório"))
.filter(p -> p.toString().endsWith(".java"))
.flatMap(p -> lines(p))
.flatMapToInt(s -> s.chars()); // Converte String → IntStream (evita boxing)
Resultado: IntStream com todos os caracteres dos arquivos.
4. Exemplo com Grupos de Usuários
Contexto:
Classe Grupo com usuários:
class Grupo {
private Set usuarios = new HashSet<>();
public void add(Usuario u) { usuarios.add(u); }
public Stream getUsuarios() { return usuarios.stream(); }
}
Lista de grupos:
List grupos = Arrays.asList(englishSpeakers, spanishSpeakers);
Problema:
grupos.stream().map(g -> g.getUsuarios()) gera Stream>.
Solução com flatMap:
grupos.stream()
.flatMap(g -> g.getUsuarios()) // Achata para Stream
.distinct() // Remove usuários duplicados
.forEach(System.out::println);
5. Exemplo com Pedidos de Usuários
Contexto:
Cada Usuario possui uma lista de Pedido:
class Usuario {
private List pedidos;
public Stream getPedidos() { return pedidos.stream(); }
}
Objetivo: Obter todos os pedidos de uma lista de usuários.
Código:
List usuarios = ...;
Stream todosPedidos = usuarios.stream()
.flatMap(u -> u.getPedidos()); // Converte Stream> → Stream
6. Considerações Finais
Diferença entre map e flatMap:
- map: Transforma elementos em outros tipos (pode gerar streams aninhados).
- flatMap: Combina múltiplos streams em um único stream.
Operações relacionadas:
- flatMapToInt, flatMapToLong, flatMapToDouble para streams primitivos.
- Cuidado: Usar operações de curto-circuito (ex: limit, findFirst) em streams potencialmente infinitos.