forEach vs forEachOrdered in Java 8 Stream
je comprends que ces méthodes diffèrent l'ordre d'exécution, mais dans tous mes tests, Je ne peux pas obtenir une exécution d'ordre différente.
exemple:
System.out.println("forEach Demo");
Stream.of("AAA","BBB","CCC").forEach(s->System.out.println("Output:"+s));
System.out.println("forEachOrdered Demo");
Stream.of("AAA","BBB","CCC").forEachOrdered(s->System.out.println("Output:"+s));
sortie:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
veuillez fournir des exemples où deux méthodes produiront des extrants différents.
3 réponses
Stream.of("AAA","BBB","CCC").parallel().forEach(s->System.out.println("Output:"+s));
Stream.of("AAA","BBB","CCC").parallel().forEachOrdered(s->System.out.println("Output:"+s));
la deuxième ligne produira toujours
Output:AAA
Output:BBB
Output:CCC
tandis que le premier n'est pas garanti puisque la commande n'est pas conservée. forEachOrdered
traitera les éléments du flux dans l'ordre spécifié par sa source, que le flux soit séquentiel ou parallèle.
citant forEach
Javadoc:
Le comportement de cette opération est explicitement non déterministe. Pour les pipelines à flux parallèle, cette opération ne garantit pas le respect de l'ordre de rencontre du flux, car cela sacrifierait le bénéfice du parallélisme.
Quand le forEachOrdered
Javadoc états (l'emphase est mienne):
effectue une action pour chaque élément de ce flux, dans l'ordre de rencontre du flux si le flux a un rencontrer afin.
bien que forEach
soit plus court et plus joli, je suggère d'utiliser forEachOrdered
dans tous les endroits où l'ordre importe de le spécifier explicitement. Pour les flux séquentiels le forEach
semble respecter l'ordre et même le code interne de l'API de flux utilise forEach
(pour flux qui est connu pour être séquentiel) où il est sémantiquement nécessaire d'utiliser forEachOrdered
! Néanmoins vous pouvez décider plus tard de changer votre flux en parallèle et votre code être rompu. Aussi quand vous utilisez forEachOrdered
le lecteur de votre code voit le message:"l'ordre importe ici". Ainsi, il documente mieux votre code.
Notez aussi que pour les flux parallèles le forEach
non seulement exécuté dans un ordre non-derménique, mais vous pouvez aussi le faire exécuter simultanément dans différents threads pour différents éléments (ce qui n'est pas possible avec forEachOrdered
).
enfin les deux forEach
/ forEachOrdered
sont rarement utile. Dans la plupart des cas, vous avez réellement besoin de produire un résultat, pas seulement des effets secondaires, donc des opérations comme reduce
ou collect
devrait être plus approprié. Exprimer l'opération de réduction par nature via forEach
est généralement considéré comme un mauvais style.
forEach () méthode effectue une action pour chaque élément de ce flux. En parallèle des flux, cette opération ne garantit pas le maintien de l'ordre du cours d'eau.
forEachOrdered () méthode effectue une action pour chaque élément de ce flux, en garantissant que chaque élément est traité dans l'ordre de rencontre pour les flux qui ont un ordre de rencontre défini.
prendre l'exemple suivant:
String str = "sushil mittal";
System.out.println("****forEach without using parallel****");
str.chars().forEach(s -> System.out.print((char) s));
System.out.println("\n****forEach with using parallel****");
str.chars().parallel().forEach(s -> System.out.print((char) s));
System.out.println("\n****forEachOrdered with using parallel****");
str.chars().parallel().forEachOrdered(s -> System.out.print((char) s));
sortie:
****forEach sans l'aide de parallèles****
sushil mittal
****forEach avec l'aide de parallèles****
mihul issltat
* * * * pour les commandes parallèles * * * *
sushil mittal