¿Cómo asegurar el orden de procesamiento en las transmisiones java8?

Quiero procesar listas dentro de un objeto java XML . Debo asegurarme de procesar todos los elementos para poder recibirlos.

¿Debería, por lo tanto, llamar de forma sequential en cada stream que uso? list.stream().sequential().filter().forEach()

¿O es suficiente usar solo la transmisión siempre que no use el paralelismo? list.stream().filter().forEach()

Usted está haciendo la pregunta incorrecta. Está preguntando acerca de sequential vs. parallel mientras que usted desea procesar los elementos en orden , por lo que debe preguntar acerca de cómo ordenarlos . Si tiene un flujo ordenado y realiza operaciones que garantizan mantener el orden, no importa si el flujo se procesa en paralelo o secuencialmente; la implementación mantendrá el orden.

La propiedad ordenada es distinta de paralela frente a secuencia. Por ejemplo, si llama a stream() en un HashSet la transmisión se desordena mientras que la llamada a stream() en una List devuelve una secuencia ordenada. Tenga en cuenta que puede llamar unordered() para liberar el contrato de pedido y posiblemente boost el rendimiento. Una vez que la transmisión no ordena, no hay forma de restablecer el pedido. (La única forma de convertir un flujo desordenado en un pedido es llamar a sorted , sin embargo, el orden resultante no es necesariamente el pedido original).

Consulte también la sección “Pedidos” de la documentación del paquete java.util.stream .

Para garantizar el mantenimiento de los pedidos a lo largo de toda una operación de flujo, debe estudiar la documentación de la fuente de la secuencia, todas las operaciones intermedias y la operación de la terminal para saber si mantienen la orden o no (o si la fuente tiene una orden en la primera) lugar).

Esto puede ser muy sutil, por ejemplo, Stream.iterate(T,UnaryOperator) crea una secuencia ordenada, mientras que Stream.generate(Supplier) crea una secuencia no ordenada . Tenga en cuenta que también cometió un error común en su pregunta, ya que cada forEach no mantiene el orden. forEachOrdered usar forEachOrdered si desea procesar los elementos del flujo en un orden garantizado.

Entonces, si su list en su pregunta es java.util.List , su método stream() devolverá una secuencia ordenada y el filter no cambiará el orden. Entonces, si llama a list.stream().filter() .forEachOrdered() , todos los elementos se procesarán secuencialmente en orden, mientras que para list.parallelStream().filter().forEachOrdered() los elementos se pueden procesar en paralelo ( por ejemplo, por el filtro), pero la acción terminal todavía se llamará en orden (lo que obviamente reducirá el beneficio de la ejecución en paralelo).

Si usted, por ejemplo, usa una operación como

 List< …> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList()); 

toda la operación puede beneficiarse de la ejecución en paralelo, pero la lista resultante siempre estará en el orden correcto, independientemente de si usa una secuencia paralela o secuencial.

list.stream (). secuencial (). filter (). forEach ()

siempre procesará la lista en orden ya que la lista misma está ordenada.

Sin embargo, si usamos

list.stream (). parallel ()

entonces la orden no está garantizada para el rest de las operaciones.