Java 8: Bonne pratique pour transmettre des flux dans les API pour les opérations paresseuses?


12

Dans les bibliothèques lourdes lambda pré-Java 8 comme Guava, les sorties utilisent des interfaces Java Collection Framework communes, il est donc facile de les transmettre aux API externes / internes et de toujours exploiter certains calculs paresseux si la méthode de bibliothèque le fait (par exemple, paresseux filter()et transform()).

Cependant, dans Java 8 Streams, l'appel pour obtenir un terminal Collection/ Mapest (c'est-à-dire désireux) et il allouera également de nouvelles structures de données pour conserver les résultats.

Pour les calculs compliqués avec plusieurs étapes et modèle de stratégie au milieu, cela provoque beaucoup d'allocations inutiles en raison des résultats intermédiaires.

Alors, les gens pensent-ils que c'est une bonne pratique pour les API internes (c'est-à-dire les stratégies de modèle de stratégie) de prendre et de retourner des Streams ou devrais-je simplement revenir aux API paresseuses mais non rationalisées (jeu de mots je suppose)?

Éditer:

Ma principale préoccupation Streamest qu'il ne peut être consommé qu'une seule fois et que passer quelque chose comme un Supplier<Stream<X>>semble extrêmement lourd. Cela vous pousse presque à passer un Collectionet puis à le refaire stream()(et à payer le coût d'une évaluation avide à ce point).


Quoi, Guava et ses amis ne sont pas mis à jour pour profiter des flux natifs?
Kilian Foth

1
Le fait d'avoir des interfaces qui prennent et retournent des flux améliore vraiment l'interopérabilité avec les fonctionnalités de flux standard. Il vous permet d'intégrer les appels à votre interface dans un pipeline de flux.
Philipp

@KilianFoth Il n'y a pas eu de sortie de Guava depuis près d'un an et il existe de nombreux articles populaires sur le remplacement de lambda de Guava par Stream; cependant, aucun d'entre eux ne traite du fait que les opérations de collecte de goyave peuvent être enthousiastes ou paresseuses.
billc.cn du

Réponses:


3

La paresse dans les flux Java 8 fonctionne de la même manière qu'auparavant pour les Iterables dans la goyave: vous devez transmettre l'itérable pour rester paresseux et l'évaluation se produit, une fois que vous avez créé une collection à partir de l'itérateur. Les flux et les itérateurs ne peuvent être consommés qu'une seule fois.

Donc, pour vos interfaces de méthode, la manière la plus générale (autorisant la paresse) est d'utiliser l'interface Stream (chaque fois que vous auriez utilisé Iterable auparavant). Comme le dit @Philipp, cela leur permet d'être utilisés dans les pipelines Stream.

Si tout va bien, puisque Stream est maintenant une interface standard Java officielle, il y aura de plus en plus d'autres bibliothèques et fonctions qui pourront travailler efficacement sur Streams directement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.