Encuentro de operaciones de terminal amigables / hostiles de orden frente a secuencias paralelas / secuenciales frente a secuencias ordenadas / no ordenadas
Inspirado poresta pregunta, Comencé a jugar con secuencias ordenadas vs no ordenadas, secuencias paralelas vs secuenciales y operaciones de terminal que respetan el orden de encuentro vs operaciones de terminal que no lo respetan.
En una respuesta a la pregunta vinculada, se muestra un código similar a este:
List<Integer> ordered = Arrays.asList(
1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4, 4, 3, 2, 1, 1, 2, 3, 4);
List<Integer> result = new CopyOnWriteArrayList<>();
ordered.parallelStream().forEach(result::add);
System.out.println(ordered);
System.out.println(result);
Y las listas son de hecho diferentes. losunordered
La lista incluso cambia de una ejecución a otra, lo que muestra que el resultado es en realidad no determinista.
Entonces creé este otro ejemplo:
CopyOnWriteArrayList<Integer> result2 = ordered.parallelStream()
.unordered()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));
System.out.println(ordered);
System.out.println(result2);
Y esperaba ver resultados similares, ya que la secuencia es paralela y desordenada (tal vezunordered()
es redundante, ya que es paralelo). Sin embargo, la lista resultante está ordenada, es decir, es igual a la lista fuente.
Entonces mi pregunta es ¿por qué se ordena la lista recopilada? Hacecollect
respeta siempre el orden de encuentro, incluso para flujos paralelos y desordenados? ¿Es lo específico?Collectors.toCollection(...)
coleccionista el que fuerza el orden de encuentro?