streams procesamiento print parte ejemplo datos con collection java java-8 java-stream

java - procesamiento - Evaluación de la corriente y perezosa



procesamiento de datos con streams de java se 8-parte 2 (3)

Estoy leyendo la API de Java 8 en la abstracción de la secuencia, pero no entiendo muy bien esta oración:

Las operaciones intermedias devuelven un nuevo flujo. Siempre son perezosos; la ejecución de una operación intermedia como filter () no realiza ningún filtrado, sino que crea un nuevo flujo que, cuando se recorre, contiene los elementos del flujo inicial que coinciden con el predicado dado. El recorrido de la fuente de la tubería no comienza hasta que se ejecuta la operación del terminal de la tubería.

Cuando una operación de filtro crea una nueva secuencia, ¿esa secuencia contiene un elemento filtrado? Parece entender que el flujo contiene elementos solo cuando se recorre, es decir, con una operación de terminal. Pero, entonces, ¿qué contiene el flujo filtrado? ¡¡¡Estoy confundido!!!


Esto significa que el filtro solo se aplica durante la operación del terminal. Piensa en algo como esto:

public Stream filter(Predicate p) { this.filter = p; // just store it, don''t apply it yet return this; // in reality: return a new stream } public List collect() { for (Object o : stream) { if (filter.test(o)) list.add(o); } return list; }

(Eso no compila y es una simplificación de la realidad pero el principio está ahí)


Las secuencias son perezosas porque las operaciones intermedias no se evalúan a menos que se invoque la operación del terminal.

Cada operación intermedia crea una nueva secuencia, almacena la operación / función proporcionada y devuelve la nueva secuencia.

El oleoducto acumula estas corrientes recién creadas.

El momento en que se llama a la operación del terminal, comienza el recorrido de los flujos y la función asociada se realiza una por una.

Los flujos paralelos no evalúan los flujos ''uno por uno'' (en el punto terminal). Las operaciones se realizan más bien simultáneamente, dependiendo de los núcleos disponibles.


Me parece que esa operación intermedia no es precisamente perezosa:

List<String> l3 = new ArrayList<String>(); l3.add("first"); l3.add("second"); l3.add("third"); l3.add("fouth"); l3.add("fith"); l3.add("sixth"); List<String> test3 = new ArrayList<String>(); try { l3.stream().filter(s -> { l3.clear(); test3.add(s); return true;}).forEach(System.out::println); } catch (Exception ex) { ex.printStackTrace(); System.out.println("!!! "); System.out.println(test3.stream().reduce((s1, s2) -> s1 += " ;" + s2).get()); }

Otput:

first null null null null null java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at test.TestParallel.main(TestParallel.java:69) !!! first ;null ;null ;null ;null ;null

Parece el número de conjuntos de iteraciones en la creación de secuencias, pero se está volviendo perezoso un nuevo elemento de secuencia.

Comparar a bucle con contador:

public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); int i = 0; while (i < list.size()) { System.out.println(list.get(i++)); list.clear(); } }

Salida:

1

Sólo una iteración esperada. Estoy de acuerdo con ese problema en el comportamiento de lanzamiento de Excepciones en flujos, pero creo que flojo significa obtener datos (o realizar alguna acción) solo cuando le pido a algún objeto que lo haga; y el recuento de datos es también datos.