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.

44
demandé sur Tunaki 2015-09-26 16:12:04

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.

54
répondu Tunaki 2015-09-26 13:18:29

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.

22
répondu Tagir Valeev 2015-09-26 13:31:28

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

0
répondu Sushil Mittal 2018-06-26 06:59:03