Me perguntaram isso em uma entrevista e não estou convencido de ter dado a melhor resposta que poderia ter. Mencionei que você pode fazer uma pesquisa paralela e que os valores nulos foram tratados por alguns meios que eu não conseguia lembrar. Agora percebo que estava pensando em opcionais. O que estou perdendo aqui? Eles afirmam que é um código melhor ou mais conciso, mas não tenho certeza se concordo.
Considerando o quão sucintamente foi respondida, parece que essa não era uma pergunta muito ampla, afinal.
Se eles estão fazendo essa pergunta em entrevistas, e claramente estão, que objetivo poderia ser útil, a não ser tornar mais difícil encontrar uma resposta? Quero dizer, o que você está procurando? Eu poderia quebrar a pergunta e ter todas as sub-perguntas respondidas, mas criar uma pergunta dos pais com links para todas as subquestões ... parece bem boba. Enquanto estamos nisso, por favor, dê-me um exemplo de uma pergunta menos ampla. Não conheço nenhuma maneira de fazer apenas parte dessa pergunta e ainda assim obter uma resposta significativa. Eu poderia fazer exatamente a mesma pergunta de uma maneira diferente. Por exemplo, eu poderia perguntar "Para que finalidade os fluxos servem?" ou "Quando eu usaria um fluxo em vez de um loop for?" ou "Por que se preocupar com fluxos em vez de com loops?" Porém, essas são exatamente a mesma pergunta.
... ou é considerado muito amplo porque alguém deu uma resposta multiponto realmente longa? Francamente, qualquer pessoa que sabe pode fazer isso com praticamente qualquer pergunta. Se você é um dos autores da JVM, por exemplo, provavelmente poderia falar sobre loops o dia inteiro, quando a maioria de nós não poderia.
"Edite a pergunta para limitá-la a um problema específico com detalhes suficientes para identificar uma resposta adequada. Evite fazer várias perguntas distintas ao mesmo tempo. Consulte a página Como pedir ajuda para esclarecer esta pergunta."
Conforme observado abaixo, foi dada uma resposta adequada que comprova que existe uma e que é fácil de fornecer.
fonte
Respostas:
Interessante que a pergunta da entrevista pergunte sobre as vantagens, sem perguntar sobre as desvantagens, pois existem as duas.
Os fluxos são um estilo mais declarativo . Ou um estilo mais expressivo . Pode ser considerado melhor declarar sua intenção no código, do que descrever como isso é feito:
... diz claramente que você está filtrando elementos correspondentes de uma lista, enquanto:
Diz "Estou fazendo um loop". O objetivo do loop está enterrado mais profundamente na lógica.
Os fluxos geralmente são mais tersos . O mesmo exemplo mostra isso. Terser nem sempre é melhor, mas se você pode ser conciso e expressivo ao mesmo tempo, tanto melhor.
Os fluxos têm uma forte afinidade com as funções . O Java 8 apresenta lambdas e interfaces funcionais, que abrem toda uma caixa de brinquedos com técnicas poderosas. Os fluxos fornecem a maneira mais conveniente e natural de aplicar funções a sequências de objetos.
Os fluxos incentivam menos mutabilidade . Isso está relacionado ao aspecto da programação funcional - o tipo de programa que você escreve usando fluxos costuma ser o tipo de programa em que você não modifica objetos.
Os fluxos incentivam o acoplamento mais flexível . Seu código de manipulação de fluxo não precisa saber a origem do fluxo ou seu eventual método de encerramento.
Os fluxos podem expressar sucintamente um comportamento bastante sofisticado . Por exemplo:
Pode olhar à primeira vista como se filtra todo o fluxo e depois retorna o primeiro elemento. Mas, de fato,
findFirst()
dirige toda a operação e, portanto, pára de maneira eficiente depois de encontrar um item.Os fluxos fornecem espaço para futuros ganhos de eficiência . Algumas pessoas compararam e descobriram que fluxos de thread único de
List
s ou matrizes na memória podem ser mais lentos que o loop equivalente. Isso é plausível porque há mais objetos e despesas gerais em jogo.Mas os fluxos escalam. Assim como o suporte interno do Java para operações de fluxo paralelo, existem algumas bibliotecas para redução de mapa distribuído usando o Streams como a API, porque o modelo se encaixa.
Desvantagens?
Desempenho : um
for
loop através de uma matriz é extremamente leve, tanto em termos de heap quanto de uso da CPU. Se a velocidade bruta e a economia de memória são uma prioridade, o uso de um fluxo é pior.Familiaridade . O mundo está cheio de programadores procedimentais experientes, de várias origens linguísticas, para quem os loops são familiares e os fluxos são novos. Em alguns ambientes, você deseja escrever um código familiar para esse tipo de pessoa.
Sobrecarga cognitiva . Devido à sua natureza declarativa e ao aumento da abstração do que está acontecendo abaixo, você pode precisar criar um novo modelo mental de como o código se relaciona com a execução. Na verdade, você só precisa fazer isso quando as coisas derem errado ou se precisar analisar profundamente o desempenho ou erros sutis. Quando "simplesmente funciona", simplesmente funciona.
Os depuradores estão melhorando, mas mesmo agora, quando você está percorrendo o código de fluxo em um depurador, pode ser um trabalho mais difícil que o loop equivalente, porque um loop simples está muito próximo das variáveis e locais de código com os quais um depurador tradicional trabalha.
fonte
Divertido sintático à parte, os Streams são projetados para trabalhar com conjuntos de dados potencialmente infinitamente grandes, enquanto matrizes, Coleções e quase todas as classes Java SE que implementam o Iterable estão inteiramente na memória.
Uma desvantagem de um fluxo é que filtros, mapeamentos etc. não podem gerar exceções verificadas. Isso faz do Stream uma péssima escolha para, digamos, operações de E / S intermediárias.
fonte
Stream<Row>
- ou seria possível escrever as própriasStream
operações de cursor de resultado de banco de empacotamento de implementação.Arrays.asList("test", null).stream().forEach(s -> System.out.println(s.length()));
Você percebeu incorretamente: operações paralelas usam
Stream
s, nãoOptional
s.Você pode definir métodos para trabalhar com fluxos: tomando-os como parâmetros, retornando-os etc. Você não pode definir um método que usa um loop como parâmetro. Isso permite uma operação de fluxo complicada uma vez e a utiliza várias vezes. Observe que o Java tem uma desvantagem aqui: seus métodos devem ser chamados em
someMethod(stream)
oposição aos do próprio fluxostream.someMethod()
, portanto, misturá-los complica a leitura: tente ver a ordem das operações emMuitos outros idiomas (C #, Kotlin, Scala, etc) permitem alguma forma de "métodos de extensão".
Mesmo quando você precisa apenas de operações sequenciais e não deseja reutilizá-las, para poder usar fluxos ou loops, operações simples nos fluxos podem corresponder a alterações bastante complexas nos loops.
fonte
Optional
é uma alternativanull
, mas não tem nada a ver com operações paralelas. A menos que "agora percebo que estava pensando em opcionais" em sua pergunta, esteja falando apenas sobrenull
manuseio?Você faz um loop sobre uma sequência (matriz, coleção, entrada, ...) porque deseja aplicar alguma função aos elementos da sequência.
Os fluxos oferecem a capacidade de compor funções em elementos de sequência e permitem implementar as funções mais comuns (por exemplo, mapeamento, filtragem, localização, classificação, coleta, ...) independentemente de um caso concreto.
Portanto, dada a tarefa de loop na maioria dos casos, você pode expressá-la com menos código usando o Streams, ou seja, você ganha legibilidade .
fonte
Eu diria que sua paralelização é tão fácil de usar. Tente iterar milhões de entradas em paralelo com um loop for. Vamos a muitos cpus, não mais rápidos; então, quanto mais fácil for correr paralelamente, melhor e com
Stream
s isso é fácil.O que eu gosto muito é a verbosidade que eles oferecem. Leva pouco tempo para entender o que eles realmente fazem e produzem, em vez de como eles fazem isso.
fonte