into - ¿Cuándo se considera que se consume un flujo de Java 8?
stream parallel java 8 (2)
Según el Stream
Javadoc :
Un flujo debe operarse en (invocar una operación de flujo intermedio o terminal) solo una vez. Esto descarta, por ejemplo, flujos "bifurcados", donde la misma fuente alimenta dos o más tuberías, o múltiples recorridos del mismo flujo. Una implementación de flujo puede lanzar la
IllegalStateException
si detecta que el flujo se está reutilizando. Sin embargo, dado que algunas operaciones de transmisión pueden devolver su receptor en lugar de un nuevo objeto de transmisión, puede que no sea posible detectar la reutilización en todos los casos.
En su caso, la llamada a filter
es detectar un intento de dividir su transmisión en dos corrientes diferentes. En lugar de esperar y causar problemas una vez que se agrega la operación del terminal, está realizando un ataque preventivo para dejar en claro cualquier rastro de pila que obtenga exactamente donde está su problema.
forEach()
entendido, se considera que un Stream
de Java 8 se consume una vez que se realiza una operación de terminal, como forEach()
o count()
.
Sin embargo, el caso de prueba multipleFilters_separate
continuación IllegalStateException
una IllegalStateException
, aunque el filter
es una operación intermedia perezosa, que se llama solo como dos declaraciones. Y, sin embargo, puedo encadenar las dos operaciones de filtro en una sola declaración y funciona.
@Test(expected=IllegalStateException.class)
public void multipleFilters_separate() {
Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
ints.filter(d -> d > 1.3);
ints.filter(d -> d > 2.3).forEach(System.out::println);
}
@Test
public void multipleFilters_piped() {
Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
ints.filter(d -> d > 1.3)
.filter(d -> d > 2.3)
.forEach(System.out::println);
}
A partir de esto, Stream
se considera que un Stream
se consume después de la primera declaración que lo usa, ya sea que esa instrucción llame a una operación de terminal o no. ¿Eso suena bien?
Una Stream
se considera consumida una vez que se ejecuta una operación de terminal. Sin embargo, incluso varias operaciones intermedias no deben ejecutarse para la misma instancia de Stream
, como se indica en el javadoc de Stream
:
Un flujo debe operarse en (invocar una operación de flujo intermedio o terminal) solo una vez . Esto descarta, por ejemplo, flujos "bifurcados", donde la misma fuente alimenta dos o más tuberías, o múltiples recorridos del mismo flujo. Una implementación de flujo puede lanzar la excepción IllegalStateException si detecta que el flujo se está reutilizando. Sin embargo, dado que algunas operaciones de transmisión pueden devolver su receptor en lugar de un nuevo objeto de transmisión, puede que no sea posible detectar la reutilización en todos los casos.
En caso de operaciones de transmisión intermedias, debe llamar a la siguiente operación en la Stream
devuelta por la operación anterior:
public void multipleFilters_separate() {
Stream<Double> ints = Stream.of(1.1, 2.2, 3.3);
ints = ints.filter(d -> d > 1.3);
ints.filter(d -> d > 2.3).forEach(System.out::println);
}