"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Java Streams: o guia definitivo para iniciantes

Java Streams: o guia definitivo para iniciantes

Publicado em 2024-11-04
Navegar:760

Então, você está aqui para aprender sobre Córregos em Java, mas não sobre o tipo de riacho onde as pessoas vão pescar ou os fluxos de água. Estamos falando de fluxos de dados, um recurso poderoso introduzido no Java 8 que torna o trabalho com dados muito mais fácil. Quer você seja novo nisso ou já tenha tentado, mas não conseguiu decifrar, não se preocupe. Acompanharei você durante toda a jornada em uma linguagem simples e fácil de entender.

Preparar? Vamos mergulhar em Java Streams!


Java Streams: The Ultimate Guide for Complete Beginners


O que é um fluxo em Java?

Um Stream é uma forma de processar dados em uma sequência. Imagine que você tem uma lista de itens e deseja fazer algo com esses itens (filtrar, classificar, mapear, etc.). Um Stream permite que você faça tudo isso de maneira limpa e eficiente. É como uma linha de montagem onde seus dados fluem por diferentes etapas até serem processados.

Principais coisas a serem lembradas sobre streams:

  1. Streams não modificam os dados originais. Pense neles como uma visualização ou um pipeline de seus dados.
  2. Streams processam dados preguiçosamente, o que significa que eles não realizam nenhum trabalho real até que você lhes diga para produzir um resultado final. Isso evita cálculos desnecessários.
  3. Streams são de uso único. Depois que um fluxo é consumido, ele desaparece. Você precisará criar um novo se quiser reutilizá-lo.

Por que usar fluxos?

Por que não usar apenas um loop for ou manipular coleções diretamente? Bem, existem três razões principais:

  • Código mais limpo: Não há necessidade de escrever loops repetitivos e volumosos. Os streams oferecem uma maneira limpa e legível de processar dados.
  • Melhor desempenho: com avaliação lenta, os streams processam os dados com mais eficiência. Eles só trabalham com dados quando necessário, o que pode economizar tempo de processamento.
  • Estilo funcional: Streams trazem um estilo de programação funcional mais declarativo para Java, o que significa que você se concentra em o que deseja fazer, não em como.

Como funcionam os fluxos? O Básico

Vamos dar uma olhada nos dois principais tipos de operações de stream: Intermediário e Terminal.

1. Operações Intermediárias

São as operações que preparam os dados, mas não produzem um resultado final imediato. Pense nisso como as etapas do “workshop”.

  • filtro()

    Isso é como uma peneira. Ele seleciona elementos com base em uma condição. Por exemplo, se você quiser apenas os números pares de uma lista de inteiros, você usaria filter().

    java
    Copy code
    List numbers = Arrays.asList(1, 2, 3, 4, 5);
    List evenNumbers = numbers.stream()
                                       .filter(n -> n % 2 == 0)
                                       .collect(Collectors.toList());
    // Output: [2, 4]
    
    

    Por que filtrar? Sem filter(), você precisaria percorrer manualmente a lista e adicionar apenas os elementos correspondentes a uma nova lista. filter() permite que você faça isso em uma etapa limpa.

  • mapa()

    Este é um transformador. Pega um elemento e retorna algo diferente. Por exemplo, se você tiver uma lista de strings e quiser o comprimento de cada string:

    java
    Copy code
    List words = Arrays.asList("apple", "banana", "cherry");
    List lengths = words.stream()
                                 .map(String::length)
                                 .collect(Collectors.toList());
    // Output: [5, 6, 6]
    
    

    Por que map? map() é usado quando você precisa transformar cada elemento em outra coisa, como converter uma lista de strings em uma lista de seus comprimentos.

  • distinto()

    É como um filtro duplicado. Isso remove elementos duplicados de um stream.

    java
    Copy code
    List numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
    List distinctNumbers = numbers.stream()
                                           .distinct()
                                           .collect(Collectors.toList());
    // Output: [1, 2, 3, 4, 5]
    
    

    Por que distinto? Em uma lista normal, você precisaria verificar manualmente se há duplicatas. distinto() faz isso para você em uma linha.

  • classificado()

    Isso classifica seus dados em ordem natural (ou personalizada, se desejar).

    java
    Copy code
    List names = Arrays.asList("Charlie", "Alice", "Bob");
    List sortedNames = names.stream()
                                    .sorted()
                                    .collect(Collectors.toList());
    // Output: ["Alice", "Bob", "Charlie"]
    
    

    Por que classificado? Em vez de escrever a lógica de classificação você mesmo, sorted() cuida disso para você.

2. Operações de Terminal

São eles que produzem o resultado final e acionam o processamento de todo o stream. Pense nisso como o "ponto de saída".

  • coletar()

    Esta é a operação de terminal mais comum. Ele reúne os resultados do fluxo e os coloca em uma lista, conjunto ou outra coleção.

    java
    Copy code
    List names = Arrays.asList("Charlie", "Alice", "Bob");
    List upperNames = names.stream()
                                   .map(String::toUpperCase)
                                   .collect(Collectors.toList());
    // Output: ["CHARLIE", "ALICE", "BOB"]
    
    

    Por que coletar? Você quase sempre usará collect() para reunir os resultados de sua transmissão em uma coleção. É sua parada final.

  • forEach()

    Se você não precisa de um resultado e deseja apenas realizar uma ação em cada item (como imprimi-los), forEach() é seu amigo.

    java
    Copy code
    numbers.stream()
           .forEach(System.out::println);
    
    

    Por que forEach? Isso é perfeito para efeitos colaterais, como imprimir dados no console ou gravar em um arquivo.

  • reduzir()

    reduce() pega um monte de dados e os resume em um único resultado. Por exemplo, somando uma lista de números:

    java
    Copy code
    int sum = numbers.stream()
                     .reduce(0, Integer::sum);
    // Output: 15
    
    

    Por que reduzir? Quando você precisa combinar ou acumular valores em um único resultado, reduzir() é a sua escolha.


Outros tipos de fluxos

Nem todos os streams são criados a partir de coleções. Java fornece outros tipos de fluxos para lidar com vários tipos de dados:


Java Streams: The Ultimate Guide for Complete Beginners


  1. IntStream, LongStream, DoubleStream

    Esses streams são especializados para lidar com tipos primitivos. Em vez de valores de boxe e unboxing como Stream, você os usa para evitar penalidades de desempenho.

    Exemplo:

    java
    Copy code
    IntStream intStream = IntStream.of(1, 2, 3, 4);
    int sum = intStream.sum();  // Output: 10
    
    
  2. Fluxo de arquivos

    Você pode criar fluxos de arquivos usando Files.lines().

    java
    Copy code
    try (Stream lines = Files.lines(Paths.get("data.txt"))) {
        lines.forEach(System.out::println);
    } catch (IOException e) {
        e.printStackTrace();
    }
    
    

    Por que usar fluxos de arquivos? Ao lidar com arquivos grandes, carregar todos os dados na memória pode não ser eficiente. Usar um fluxo permite processá-lo linha por linha.


Quando usar fluxos?

  • Transformando Dados: Quando você precisa modificar cada elemento de uma coleção.
  • Filtragem: Quando você deseja selecionar apenas os dados que correspondem a determinadas condições.
  • Agregação de dados: quando você precisa reduzir uma coleção em um único resultado (por exemplo, soma, média).
  • Processamento Paralelo: Streams também suportam paralelismo. Com .parallelStream(), você pode dividir suas tarefas em vários threads para um processamento mais rápido.

Stream vs. Loops: Por que não usar apenas Loops?

Boa pergunta! Vamos comparar:

  1. Legibilidade: com Streams, você se concentra em o que deseja fazer, não em como. Loops tendem a fazer você escrever muitos códigos clichês extras (como contadores e condicionais).
  2. Desempenho: Streams são otimizados para lidar com grandes dados de forma eficiente, especialmente com avaliação lenta e paralelismo. Os loops não oferecem essas otimizações prontas para uso.
  3. Flexibilidade: Streams permitem encadear operações (como filtragem, mapeamento e redução) em um estilo limpo e funcional. Os loops exigiriam que você aninhe mais lógica dentro deles.

Concluindo

Streams em Java visam simplificar a maneira como você processa dados. Eles tornam seu código mais legível, mais fácil de manter e mais eficiente ao trabalhar com coleções. Esteja você filtrando, transformando ou reduzindo dados, o Streams oferece métodos claros e diretos que eliminam a necessidade de loops volumosos e trabalho manual.

Agora que você está bem equipado com o básico do Streams, por que parar aqui? Siga-me no Twitter, LinkedIn ou confira meu blog para mais dicas de Java que farão de você um profissional rapidamente! E se você achou este guia útil, compartilhe-o com seus colegas desenvolvedores, porque compartilhar é cuidar!


Pronto para experimentar? Vamos fazer esse Stream fluir em seu próximo projeto!

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/wittedtech-by-harshit/java-streams-the-ultimate-guide-for-complete-beginners-40e2?1 Se houver alguma violação, entre em contato com study_golang@163 .com para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3