parallel into instream ejemplo divided java java-8 java-stream

into - ¿Por qué no se ejecuta Java close() después de emitir una operación de terminal?



stream parallel java 8 (3)

¿Por qué la biblioteca Java 8 no se encarga de cerrar las secuencias después de cada operación de terminal (sin tener que ajustar la creación de instancias de la secuencia en un intento de recursos)?

Debido a que puede producirse una excepción durante o antes de la operación del terminal, y porque es posible que no desee que la operación del terminal cierre la secuencia. Puedes usar try-with-resource si definitivamente quieres que la secuencia se cierre.

Si corresponde, ¿existe algún plan para agregar esta funcionalidad a Java o tendría sentido solicitarla?

No tendría sentido, ver respuesta arriba.

Después de leer https://www.airpair.com/java/posts/spring-streams-memory-efficiency , me siento tentado a transmitir los resultados de una base de datos, pero como comenté con un colega (cfr. Comentario, agregó a eso artículo), es necesario recordar utilizar la construcción try-with-resources para evitar cualquier pérdida de memoria.

  1. ¿Por qué la biblioteca Java 8 no se encarga de cerrar las secuencias después de cada operación de terminal (sin tener que ajustar la creación de instancias de la secuencia en un intento de recursos)?
  2. Si corresponde, ¿existe algún plan para agregar esta funcionalidad a Java o tendría sentido solicitarla?

Creo que estás mezclando java.io.InputStream con java.util.stream.Stream , que son dos conceptos muy diferentes.

try-with-resources funciona en objetos que implementan la interfaz de Autoclosable , como InputStream s. InputStream s representa una fuente abstracta de datos relacionados con IO .

java.util.stream.Stream<T> por otro lado, implementa un concepto de programación funcional, que representa un tipo de colección dinámica que no se construye necesariamente de forma estática, sino que puede generarse y, por consiguiente, potencialmente infinita.

Lo que Marko Topolnik (el autor del artículo al que has vinculado) hace esencialmente en el artículo, es sugerir una forma de incluir una fuente de IO en un java.util.stream.Stream . Este es un enfoque bastante inteligente, pero los java.util.stream.Stream no están, en general, destinados a este propósito.

Debido a que, en general, no están diseñados para usarse con IO , no hay razón para que incluyan el cierre después de las operaciones de la terminal.

EDITAR :

Después de aclarar que, de hecho, no había mezclado los dos (perdón por suponer que sí), gracias a esta respuesta , descubrí que su ejemplo exacto se encuentra en la documentación de AutoCloseable (énfasis agregado por mí mismo):

Es posible, y de hecho común, que una clase base implemente AutoCloseable aunque no todas sus subclases o instancias tengan recursos liberables. Para el código que debe operar en generalidad completa, o cuando se sabe que la instancia de AutoCloseable requiere la liberación de recursos, se recomienda usar construcciones de prueba con recursos. Sin embargo, cuando se utilizan recursos como Stream que admiten tanto formularios basados ​​en E / S como no basados ​​en E / S, los bloques try-with-resources en general no son necesarios cuando se utilizan formularios no basados ​​en I / O.


Debido a que las transmisiones que requieren la liberación explícita de recursos es realmente un caso bastante inusual Así que optamos por no cargar la ejecución de todos los flujos con algo que solo es valioso para el .01% de los usos.

Hicimos Stream Autocloseable para que pueda liberar recursos de la fuente si lo desea, pero aquí es donde paramos, y por una buena razón.

No solo haría esta carga automática para la mayoría de los usuarios con un trabajo adicional que no necesitan, sino que también violaría un principio general: el que asigna el recurso es responsable de cerrar el recurso. Cuando usted llama

BufferedReader reader = ... reader.lines().op().op()...

usted es el que abre el recurso, no la biblioteca de secuencias, y debe cerrarlo. De hecho, dado que el cierre de un flujo resultante de llamar a un método de acceso en algún objeto que contiene recursos a veces cerrará el objeto subyacente, es probable que no desee que el flujo cierre el BufferedReader por usted, es posible que desee que permanezca abierto después del llamada.

Si quieres cerrar el recurso, esto también es fácil:

try (BufferedReader reader = ...) { reader.lines().op()... }

Probablemente esté utilizando las transmisiones de una manera particular, por lo que probablemente parece "obvio" lo que deberían hacer las transmisiones, pero existen más casos de uso que los suyos. Entonces, en lugar de atender casos de uso específicos, lo abordamos desde el principio general: si abrió el flujo y desea cerrarlo, ciérrelo usted mismo, pero si no lo abrió, no es para que lo cierre.