Java 8: ¿Buena práctica para transmitir Streams en API para operaciones diferidas?

12

En bibliotecas anteriores a Java 8 lambda-heavy como Guava, las salidas usan interfaces comunes de Java Collection Framework, por lo que es fácil pasarlas a API externas / internas y aún aprovechar algunos cálculos perezosos si el método de la biblioteca lo hace (por ejemplo, perezoso filter()y transform()).

Sin embargo, en Java 8 Streams, la llamada para obtener un terminal Collection/ Mapes (es decir, ansioso) y también asignará nuevas estructuras de datos para contener los resultados.

Para cálculos complicados con múltiples etapas y patrones de estrategia en el medio, esto causa muchas asignaciones innecesarias debido a los resultados intermedios.

Entonces, ¿la gente piensa que es una buena práctica para las API internas (es decir, estrategias de patrones de estrategia) tomar y regresar Streams o debería simplemente recurrir a las API de guayaba perezosas pero no simplificadas (juego de palabras, supongo)?

Editar:

Mi principal preocupación Streames que solo se puede consumir una vez y pasar algo parecido a un se Supplier<Stream<X>>ve extremadamente engorroso. Casi lo empuja a pasar un Collectiony luego volverlo stream()(y pagar el costo de una evaluación entusiasta en ese punto).

billc.cn
fuente
¿Qué, guayaba y amigos no se actualizan para aprovechar las transmisiones nativas?
Kilian Foth
1
Tener interfaces que toman y devuelven flujos realmente mejora la interoperabilidad con las funcionalidades de flujo estándar. Le permite integrar llamadas a su interfaz en una tubería de flujo.
Philipp
@KilianFoth No ha habido ningún lanzamiento de Guava en casi un año y hay muchos artículos populares sobre el reemplazo de las cosas lambda de Guava con Stream; sin embargo, ninguno de ellos aborda el hecho de que las operaciones de recolección de guayaba pueden ser ansiosas o flojas.
billc.cn

Respuestas:

3

La pereza en Java 8 Streams funciona de la misma manera que lo hacía para Iterables en Guava: debe pasar el Iterable para mantenerse perezoso y la evaluación ocurre, una vez que crea una Colección desde el Iterador. Tanto Streams como Iterators solo se pueden consumir una vez.

Entonces, para sus interfaces de método, la forma más general (permitiendo la pereza) es usar la interfaz Stream (siempre que haya usado Iterable antes). Como dice @Philipp, esto les permite ser utilizados en tuberías de Stream.

Con suerte, dado que Stream ahora es una interfaz estándar oficial de Java, habrá cada vez más otras bibliotecas y funciones que pueden funcionar de manera eficiente en Streams directamente.

Robert Jack Will
fuente