8.9 FlatMap – DEV Community

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  
Enter fullscreen mode

Exit fullscreen mode

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)  
Enter fullscreen mode

Exit fullscreen mode

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(); }  
}  
Enter fullscreen mode

Exit fullscreen mode

Lista de grupos:

List grupos = Arrays.asList(englishSpeakers, spanishSpeakers);  
Enter fullscreen mode

Exit fullscreen mode

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);  
Enter fullscreen mode

Exit fullscreen mode

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(); }  
}  
Enter fullscreen mode

Exit fullscreen mode

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  
Enter fullscreen mode

Exit fullscreen mode

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.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *