rapido por organizarme organizar organizando organización ordenar minutos limpiar habitación cuarto como casas casa java list java-8

java - por - ¿Está garantizado.collect para ser ordenado en corrientes paralelas?



organizar casas (2)

TL; DR

Sí, el pedido está garantizado.

Stream.collect () documentación de la API

El punto de partida es mirar qué determina si una reducción es concurrente o no. La descripción de Stream.collect() dice lo siguiente:

Si el flujo es paralelo, y el Collector es concurrent , y si el flujo no está ordenado o el recopilador unordered está unordered , se realizará una reducción concurrente (consulte el Collector para obtener detalles sobre la reducción simultánea).

Se cumple la primera condición: el flujo es paralelo. ¿Qué hay de la segunda y la tercera: es el Collector concurrente y desordenado?

Collectors.toList () documentación de la API

toList() lee:

Devuelve un Collector que acumula los elementos de entrada en una nueva List . No hay garantías sobre el tipo, la mutabilidad, la serialización o la seguridad de subprocesos de la List devuelta; Si se requiere más control sobre la List devuelta, use toCollection(Supplier) .

Devoluciones:
un recopilador que recopila todos los elementos de entrada en una lista, en orden de encuentro

Una operación que funciona en orden de encuentro opera sobre los elementos en su orden original. Esto anula el paralelismo.

Código de implementación

La inspección de la implementación de Collectors.java confirma que toList() no incluye los rasgos CONCURRENT o UNORDERED .

public static <T> Collector<T, ?, List<T>> toList() { return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add, (left, right) -> { left.addAll(right); return left; }, CH_ID); } // ... static final Set<Collector.Characteristics> CH_ID = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));

Observe cómo el recopilador tiene el CH_ID rasgos CH_ID , que tiene solo el único rasgo IDENTITY_FINISH . CONCURRENT y UNORDERED no están allí, por lo que la reducción no puede ser simultánea.

Una reducción no concurrente significa que, si la secuencia es paralela, la recopilación puede proceder en paralelo, pero se dividirá en varios resultados intermedios confinados en subprocesos que luego se combinan. Esto asegura que el resultado combinado esté en orden de encuentro.

Vea también: ¿Por qué la transmisión paralela se recopila secuencialmente en Java 8?

Dado que tengo una lista de Strings List<String> toProcess . Los resultados deben estar en el orden en que se dieron las líneas originales. Quiero utilizar las nuevas corrientes paralelas.

¿El siguiente código garantiza que los resultados estarán en el mismo orden en que estaban en la lista original?

// ["a", "b", "c"] List<String> toProcess; // should be ["a", "b", "c"] List<String> results = toProcess.parallelStream() .map(s -> s) .collect(Collectors.toList());


Usted está garantizado para obtener los elementos en orden de encuentro.

De la documentación de toList :

Devoluciones: un recopilador que recopila todos los elementos de entrada en una lista, en orden de encuentro

Consulte el resumen de java.util.streams para obtener más información sobre el término "orden de encuentro".

Además, la documentación del List#spliterator requiere que todas las implementaciones de List produzcan divisores que SE ORDENAN:

El Spliterator informa sobre Spliterator.SIZED y Spliterator.ORDERED. Las implementaciones deben documentar el reporte de valores característicos adicionales.

Por extraño que parezca, mientras que la interfaz de la List requiere que el iterator() produzca elementos en la "secuencia adecuada", solo se debe ordenar el spliterator() pero no se requiere específicamente que siga el orden natural de la lista.

Entonces, para responder a su pregunta, se garantiza que la lista producida por toList contendrá los elementos exactamente como los ordena el separador de la lista de origen . No importa si el flujo es paralelo o secuencial.