Java 8: Boas práticas para transmitir Streams nas APIs para operações preguiçosas?

12

Em bibliotecas pré-Java 8 pesadas para lambda como Guava, as saídas usam interfaces comuns do Java Collection Framework, portanto é fácil transmiti-las para APIs externas / internas e ainda aproveitar uma computação lenta se o método da biblioteca o fizer (por exemplo, lazy filter()e transform()).

No entanto, em Java 8 Streams, a chamada para obter um Collection/ Mapé terminal (ou seja ansioso) e que também irá alocar novas estruturas de dados para armazenar os resultados.

Para cálculos complicados com vários estágios e padrão de estratégia no meio, isso causa muitas alocações desnecessárias devido aos resultados intermediários.

Então, as pessoas pensam que é uma boa prática para APIs internas (ou seja, estratégias de padrão de estratégia) obter e retornar Streams ou devo apenas recorrer às APIs Guava preguiçosas, mas não simplificadas (trocadilhos, acho?)?

Editar:

Minha principal preocupação Streamé que ele só pode ser consumido uma vez e passar algo como um Supplier<Stream<X>>parece extremamente complicado. Quase o empurra apenas para passar em um Collectione depois devolvê- stream()lo (e pagando o custo de uma avaliação ágil naquele momento).

billc.cn
fonte
O que, goiaba e amigos não estão sendo atualizados para aproveitar os fluxos nativos?
precisa
1
Ter interfaces que recebem e retornam fluxos realmente melhora a interoperabilidade com as funcionalidades de fluxo padrão. Ele permite integrar chamadas à sua interface em um pipeline de fluxo.
Philipp
@KilianFoth Não há nenhum lançamento do Guava há quase um ano e há muitos artigos populares sobre a substituição do material lambda do Guava pelo Stream; no entanto, nenhum deles aborda o fato de que as operações de coleta de goiaba podem ser ansiosas ou preguiçosas.
billc.cn

Respostas:

3

Preguiça no Java 8 Streams funciona da mesma maneira que costumava para os Iterables na Guava: você precisa passar o Iterable para ficar preguiçoso e a avaliação acontece, depois que você cria uma coleção a partir do Iterator. Streams e Iteradores podem ser consumidos apenas uma vez.

Portanto, para as interfaces de método, a maneira mais geral (permitindo a preguiça) é usar a interface Stream (sempre que você tivesse usado o Iterable antes). Como o @Philipp diz, isso permite que eles sejam usados ​​nos pipelines de Stream.

Felizmente, como o Stream agora é uma interface padrão oficial do Java, haverá mais e mais bibliotecas e funções que podem trabalhar eficientemente diretamente no Streams.

Robert Jack Will
fonte