Estás haciendo la pregunta equivocada. Usted está preguntando acerca de sequential
vs. parallel
mientras que desea procesar los artículos en orden , por lo que debe preguntar sobre el pedido . Si tiene una secuencia ordenada y realiza operaciones que garantizan mantener la orden, no importa si la secuencia se procesa en paralelo o secuencial; La implementación mantendrá el orden.
La propiedad ordenada es distinta de paralela versus secuencial. Por ejemplo, si llama stream()
a un HashSet
flujo, el flujo no estará ordenado mientras llama stream()
y List
devuelve un flujo ordenado. Tenga en cuenta que puede llamar unordered()
para liberar el contrato de pedido y potencialmente aumentar el rendimiento. Una vez que la secuencia no tiene orden, no hay forma de restablecer el orden. (La única forma de convertir una secuencia no ordenada en una ordenada es llamar sorted
, sin embargo, la orden resultante no es necesariamente la orden original).
Consulte también la sección "Pedidos" de la java.util.stream
documentación del paquete .
Para garantizar el mantenimiento del pedido a lo largo de una operación de flujo completo, debe estudiar la documentación de la fuente del flujo, todas las operaciones intermedias y la operación del terminal para saber si mantienen el pedido o no (o si la fuente tiene un pedido en el primer sitio).
Esto puede ser muy sutil, por ejemplo, Stream.iterate(T,UnaryOperator)
crea una secuencia ordenada mientras Stream.generate(Supplier)
crea una secuencia no ordenada . Tenga en cuenta que también cometió un error común en su pregunta, ya que no mantiene el orden. Debe usarlo si desea procesar los elementos de la secuencia en un orden garantizado.forEach
forEachOrdered
Entonces si tu list
pregunta es realmente un java.util.List
, su stream()
método devolverá una secuencia ordenada y filter
no cambiará el orden. Entonces, si llama list.stream().filter() .forEachOrdered()
, todos los elementos se procesarán secuencialmente en orden, mientras que para list.parallelStream().filter().forEachOrdered()
los elementos podrían procesarse en paralelo (por ejemplo, por el filtro), pero la acción terminal aún se llamará en orden (lo que obviamente reducirá el beneficio de la ejecución en paralelo) .
Si, por ejemplo, usa una operación como
List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());
toda la operación podría beneficiarse de la ejecución paralela, pero la lista resultante siempre estará en el orden correcto, independientemente de si usa una secuencia paralela o secuencial.
List<>
que preservará el orden, peroCollection<>
¿lo hará ?Set
s generalmente no, a menos que sea unSortedSet
oLinkedHashSet
. Las vistas de recopilación de aMap
(keySet()
,entrySet()
yvalues()
) heredan laMap
política de 's, es decir, se ordenan cuando el mapa es unSortedMap
oLinkedHashMap
. El comportamiento está determinado por las características informadas por el spliterator de la colección . Ladefault
implementación deCollection
no informa laORDERED
característica, por lo que está desordenada, a menos que se anule.forEachOrdered
solo difiereforEach
cuando se usan flujos paralelos, pero es una buena práctica usarlo de todos modos cuando se ordena, en caso de que el método de vapor cambie ...En una palabra:
El pedido depende de la estructura de datos de origen y las operaciones de flujo intermedio. Suponiendo que esté utilizando un,
List
el procesamiento debe ordenarse (yafilter
que no cambiará la secuencia aquí).Más detalles:
Secuencial vs Paralelo vs No ordenado:
Javadocs
Orden de flujo:
Javadocs
fuente