Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Streams em JAVA: Tudo que você precisa saber

Posted on Sep 5 Vamos começar com um exemplo?No exemplo acima, temos um código que descreve com detalhes o que deve ser feito para chegarmos em um resultado (o resultado do exemplo apresentado), e se mudarmos o algoritmo, precisamos mudar o código, mesmo que o algoritmo seja o mesmo. Não necessariamente precisa ser assim, em SQL, por exemplo, escreveríamos:Note que no exemplo acima, descrevemos ao código o que queremos que seja feito, as premissas, descrevemos o resultado, e não como o resultado deve ser computado.Tudo certo, se o código faz parte de uma lista ou qualquer coleção, podemos tentar implementar assim:ERRADO! A API de collections não provê esse tipo de operações, o código acima não compila 😄!Imagine que essas operações são feitas em uma lista de 1.000.000 de pessoas! Portanto, após o primeiro map, você teria uma Lista com 1.000.000 de inteiros de idade (porque o map não reduziria o tamanho em si), acho que já deu para perceber que duplicar a collection vai ser altamente custoso para o processador e para a memória💡 Um objeto de Stream oferece operações de map / filter / reduce sem duplicação e com máxima eficiência!Mas como isso funciona? Quando usamos pessoas.stream(), retornamos uma Stream. Por definição, um objeto de stream não carrega dados, é grátis cria-lo.A collection is an in-memory data structure to hold values and before we start using collection, all the values should have been populated. Whereas a java Stream is a data structure that is computed on-demand. Java Stream doesn’t store data, it operates on the source data structure (collection and array) and produce pipelined data that we can use and perform specific operations. https://www.digitalocean.com/community/tutorials/java-8-streamStreams atuam sobre coleções para realizar map / filter / reduce, operações intermediárias são operações sobre streams que retornam streams ( Stream map() → Método de stream, retorna stream). Operações finais são operações que retornam a coleção de novo, depois do processamento / pipelining acabar toList() é um exemploAqui está um exemplo de como ficaria o código.💡 Importante: Você não pode processar a mesma stream duas vezes:Esse código quebrará, tendo em vista que estamos processando a mesma stream personNames duas vezes!Nesse caso, estamos aplicando o map para criar duas streams diferentes, não quebrará o código.Esse código, processando duas streams diferentes também funcionaráPor favor, não crie variáveis para trabalhar com streams, fiz por didáticaFlatmapping funciona para lidar com relações 1:NExemplo: Cidades, onde temos várias pessoas por cidade.Suponha que queremos pegar todas as pessoas, independente de suas cidades. Nesse caso, nos preocupamos com a entidade relacionada, não com as cidades em si*. O flatmap faz isso, pega uma entidade Cidade e retorna para nós uma Stream.*💡 Uma operação de flatmap recebe um objeto e retorna uma stream de outros objetosO flatmap funciona nesse caso, pois ao aplicar flatMap(Arrays::stream), você está dizendo ao Java para pegar cada array de caracteres da Stream e transformá-lo em uma stream de strings (Stream) usando o método estático Arrays.stream().Ao fazermos dessa forma, criamos um array intermediário, perdemos o propósito de streams.Podemos fazer:Em java, existem interfaces de stream feitas para manipular certos primitivos mais adequadamente, um exemplo disso é a IntStreamIntStream tende a ser mais eficiente em termos de espaço e desempenho quando você está trabalhando com valores inteiros primitivos, uma vez que evita a criação de objetos Integer.A IntStream oferece operações especializadas para trabalhar com valores inteiros, como sum(), average(), range(), rangeClosed(), etc. Uma Stream fornece operações de stream genéricas aplicáveis a objetos, mas é menos eficiente quando se trata de cálculos com tipos primitivos.💡 Além do IntStream, também existem LongStreame DoubleStream(Além da Stream)Streams não são uma boa para realizarem múltiplas tarefas simultaneamente, portanto se temos um for loop que agrega valores à 3 variáveis diferentes, precisamos dividir em 3 for’s (repetidos) e trocar cada um deles por uma stream. Claro, isso diminui muito a performance, mas em um for com poucos elementos a serem iterados, será basicamente imperceptível.Antes, ouvimos que redução era algo similar a uma agregação do SQL, vamos continuar com isso em mente, mas como isso funciona?Vamos ter como exemplo a soma, a soma é uma uma implementação de BinaryOperator, que pega dois elementos e os soma ( sum = (i1,i2) -> i1+i2;). Isso acontece com dois elementos por vez, associando os valores e depois somando com o outro.Mas e qual a redução de uma Stream vazia? A redução de uma Stream vazia é o seu elemento identidade (identity), um elemento identidade é um valor pré-definido que atua como ponto de partida em uma operação de redução. Em contextos de programação funcional, quando não há elementos para combinar na Stream, a operação de redução retorna o elemento identidade como resultado, garantindo que a operação seja definida e não cause exceções em casos de Stream vazia. Isso é especialmente útil para lidar com casos em que não há dados disponíveis para a operação específica, permitindo que o código se comporte de maneira previsível e segura.Por exemplo, o identity de uma soma é 0, tendo em vista que o 0 não impactará no valor final, para múltiplicação, um.O "identity element" ou valor inicial para as operações de max, min e average em Streams do Java é um pouco diferente porque essas operações retornam um Optional, que pode ser vazio (caso a Stream esteja vazia) ou conter um valor, portanto, essas operações não tem valores identity.Portanto, para acessar max, min e avg, você deve fazer algo do tipo:Talvez você esteja se perguntando o porquê de entendermos também a fundamentação de identity elements, se ainda não ficou claro, vai ficar agora:A operação reduce em Streams do Java tem dois parâmetros principais:💡 Se você não passar um identity correto, o resultado estará incorreto.Se sua stream não possuir um identity, você pode usar uma outra sobrecarga do método que não recebe o identity, mas retorna um Optional. Use-o somente se não possuir o identity…Reduções em um container mutável referem-se à aplicação de operações de redução, como soma, multiplicação, média, entre outras, a elementos armazenados em um contêiner que pode ser alterado durante o processo de redução. Um "container" neste contexto pode ser definido como uma estrutura de dados flexível que permite armazenar e modificar elementos de forma dinâmica (Lists, Maps, etc.). Portanto, podemos simplificar reduções em containers mutáveis como reduções em coleções.Ao chamar .stream() em uma lista, você está criando uma Stream dos elementos contidos na lista. A Stream é uma sequência de elementos que pode ser processada de maneira funcional, mas não modifica a lista original. Quando você chama .max(), por exemplo, está solicitando o elemento máximo com base em algum critério da lista, mas a lista em si permanece a mesma.Mas esse exemplo acima não é muito diferente do que já vimos, por que estamos focando nesse tipo de redução?Para filtrar e coletar elementos em uma nova lista usando a API de Streams do Java, você deve usar um coletor adequado, como Collectors.toList()Os coletores permitem que você capture os resultados das operações de redução em coleções ou outros tipos de dados concretos. Em outras palavras, eles transformam os elementos processados em uma Stream em uma coleção real que pode ser usada e manipulada posteriormente.”O novo método Stream.toList() não produz nem uma lista não modificável nem é um atalho para collect(toUnmodifiableList()), porque toUnmodifiableList() **não aceita valores nulos. A implementação de Stream.toList() não é limitada pela interface Collector; portanto, Stream.toList() aloca menos memória. Isso a torna ideal para uso quando o tamanho da stream é conhecida antecipadamente.” Link para comentário no stackoverflow💡 Não necessariamente precisamos de collectors para trabalhar com coleções, mas eles tornam a vida mais fácil, veja os dois exemplos anteriores:À medida que exploramos as reductions e operações terminais, é crucial considerar o potencial das streams paralelas em Java, mas o que são? 🤔Streams paralelas oferecem a capacidade de executar operações em paralelo, aproveitando múltiplos núcleos da CPU, o que melhora muito o desempenho da stream.Apesar disso, vale dizer que operações em paralelo nem sempre podem ser consideradas em uma stream, suponha que você esteja calculando uma média com uma reduction, para calcularmos a média, precisamos primeiro somar os elementos, e então dividirmos, se somarmos e depois dividirmos partes distintas, isso trará um resultado incorreto, isso significa que a média é uma operação não associativa!São operações em que a ordem em que os elementos são combinados não afeta o resultado. Exemplos comuns de operações associativas incluem soma e multiplicação.São o oposto!Obrigado pela leitura, espero que tenha sido produtiva e que você tenha todo o conhecimento necessário para conseguir dar seus próprios passos e construir streams funcionais e avançadas, caso necessário.https://app.pluralsight.com/library/courses/692a1310-42db-4f3c-a33b-208a55b7bd84/table-of-contentshttps://www.digitalocean.com/community/tutorials/java-8-streamMaratona Java Virado no Jirayahttps://acervolima.com/coletores-java/Templates let you quickly answer FAQs or store snippets for re-use.Peguei o texto do meu notion e post do medium, caso haja algum problema que não percebi, me avisem! Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well Confirm For further actions, you may consider blocking this person and/or reporting abuse Shai Almog - Aug 15 SnykSec - Aug 15 Nicolas Frankel - Aug 8 António Macave - Aug 15 Once suspended, kauegatto will not be able to comment or publish posts until their suspension is removed. Once unsuspended, kauegatto will be able to comment and publish posts again. Once unpublished, all posts by kauegatto will become hidden and only accessible to themselves. If kauegatto is not suspended, they can still re-publish their posts from their dashboard. Note: Once unpublished, this post will become invisible to the public and only accessible to Kauê Gatto. They can still re-publish the post if they are not suspended. Thanks for keeping DEV Community safe. Here is what you can do to flag kauegatto: kauegatto consistently posts content that violates DEV Community's code of conduct because it is harassing, offensive or spammy. Unflagging kauegatto will restore default visibility to their posts. DEV Community — A constructive and inclusive social network for software developers. With you every step of your journey. Built on Forem — the open source software that powers DEV and other inclusive communities.Made with love and Ruby on Rails. DEV Community © 2016 - 2023. We're a place where coders share, stay up-to-date and grow their careers.



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

Streams em JAVA: Tudo que você precisa saber

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×