forEach vs forEachOrdered in Java 8 Stream

Ik begrijp dat deze methoden de uitvoeringsvolgorde verschillen, maar in al mijn tests kan ik geen verschillende uitvoeringsvolgorde bereiken.

Voorbeeld:

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));

Uitvoer:

forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC

Geef voorbeelden wanneer 2 methoden verschillende resultaten opleveren.


Antwoord 1, autoriteit 100%

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));

De tweede regel wordt altijd weergegeven

Output:AAA
Output:BBB
Output:CCC

terwijl de eerste niet wordt gegarandeerd omdat de bestelling niet wordt bewaard. forEachOrderedverwerkt de elementen van de stream in de volgorde gespecificeerd door de bron, ongeacht of de stream sequentieel of parallel is.

Citaat uit forEachJavadoc:

Het gedrag van deze bewerking is expliciet niet-deterministisch. Voor parallelle stroompijplijnen garandeert deze bewerking niet dat de ontmoetingsvolgorde van de stroom wordt gerespecteerd, omdat dit het voordeel van parallellisme zou opofferen.

Wanneer de forEachOrderedJavadoc-staten (nadruk van mij):

Voert een actie uit voor elk element van deze stream, in de ontmoetingsvolgorde van de streamals de stream een ​​gedefinieerde ontmoetingsvolgorde heeft.


Antwoord 2, autoriteit 32%

Hoewel forEachkorter is en er mooier uitziet, raad ik aan om forEachOrderedte gebruiken op elke plaats waar volgorde belangrijk is om dit expliciet te specificeren. Voor opeenvolgende streams lijkt de forEachde volgorde te respecteren en zelfs de interne API-code te streamen gebruiktforEach(voor stream waarvan bekend is dat deze sequentieel is) waar het semantisch is nodig om forEachOrderedte gebruiken! Desalniettemin kunt u later besluiten om uw stream naar parallel te schakelen en wordt uw code verbroken. Ook wanneer u forEachOrderedgebruikt, ziet de lezer van uw code het bericht: “de bestelling is hier belangrijk”. Zo documenteert het uw code beter.

Houd er ook rekening mee dat voor parallelle streams de forEachniet alleen in niet-determenistische volgorde wordt uitgevoerd, maar dat u het ook gelijktijdig in verschillende threads voor verschillende elementen kunt laten uitvoeren (wat niet mogelijk is met forEachOrdered).

Ten slotte zijn beide forEach/forEachOrderedzelden nuttig. In de meeste gevallen moet je een bepaald resultaat produceren, niet alleen een neveneffect, dus bewerkingen zoals reduceof collectzouden meer geschikt moeten zijn. Het uitdrukken van reducerende handelingen via forEachwordt meestal als een slechte stijl beschouwd.


Antwoord 3, autoriteit 17%

De methode

forEach()voert een actie uit voor elk element van deze stream. Voor parallelle streams garandeert deze bewerking niet dat de volgorde van de stream behouden blijft.

De methode

forEachOrdered()voert een actie uit voor elk element van deze stream en garandeert dat elk element wordt verwerkt in de ontmoetingsvolgorde voor streams met een gedefinieerde ontmoetingsvolgorde.

neem het onderstaande voorbeeld:

   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));

Uitvoer:

****forEach without using parallel****
sushil mittal
****forEach with using parallel****
mihul issltat
****forEachOrdered with using parallel****
sushil mittal

Antwoord 4

We kunnen de voordelen van parallellisme verliezen als we forEachOrdered() gebruiken met parallelle streams.

Zoals we weten, zal het In parallel-programmeerelement parallel worden afgedrukt als we de methode forEach() gebruiken. dus de bestelling zal niet worden vastgesteld. Maar bij het gebruik van forEachOrdered() vaste volgorde in parallelle streams.

Stream.of(“AAA”,”BBB”,”CCC”).forEachOrdered(s->System.out.println(“Output:”+s));
Uitgang: AAA
Uitgang:BBB
Uitgang: CCC

Other episodes