Ich verstehe, dass diese Methoden die Ausführungsreihenfolge unterscheiden, aber in all meinen Tests kann ich keine unterschiedliche Ausführungsreihenfolge erreichen.
Beispiel:
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));
Ausgabe:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
Bitte geben Sie Beispiele an, wenn 2 Methoden unterschiedliche Ausgaben erzeugen.
java
foreach
java-8
java-stream
gstackoverflow
quelle
quelle
Antworten:
Die zweite Zeile wird immer ausgegeben
Der erste ist nicht garantiert, da die Bestellung nicht eingehalten wird.
forEachOrdered
verarbeitet die Elemente des Streams in der von seiner Quelle angegebenen Reihenfolge, unabhängig davon, ob der Stream sequentiell oder parallel ist.Zitat aus
forEach
Javadoc:Wenn der
forEachOrdered
Javadoc sagt (Schwerpunkt Mine):quelle
forEachOrdered
mit zu verwendenparallel
?Obwohl
forEach
kürzer und hübscher aussieht, würde ich empfehlen, sieforEachOrdered
an jedem Ort zu verwenden, an dem die Reihenfolge wichtig ist, um dies explizit anzugeben. Für sequentielle StreamsforEach
scheint das die Reihenfolge zu respektieren und sogar den internen Code der Stream-API zu verwendenforEach
(für Streams, von denen bekannt ist, dass sie sequentiell sind), wo es semantisch notwendig ist, sie zu verwendenforEachOrdered
! Trotzdem können Sie später entscheiden, Ihren Stream auf parallel zu ändern, und Ihr Code wird beschädigt. Auch wenn SieforEachOrdered
den Leser Ihres Codes verwenden, wird die Meldung angezeigt: "Hier ist die Reihenfolge wichtig". So wird Ihr Code besser dokumentiert.Beachten Sie auch, dass für parallele Streams diese
forEach
nicht nur in nicht deterministischer Reihenfolge ausgeführt werden, sondern dass Sie sie auch gleichzeitig in verschiedenen Threads für verschiedene Elemente ausführen lassen können (was mit nicht möglich istforEachOrdered
).Schließlich sind beide
forEach
/forEachOrdered
selten nützlich. In den meisten Fällen müssen Sie tatsächlich ein Ergebnis erzielen, nicht nur eine Nebenwirkung. Daher mögenreduce
odercollect
sollten Operationen besser geeignet sein. Das Ausdrücken eines von Natur aus reduzierenden Betriebs überforEach
wird normalerweise als schlechter Stil angesehen.quelle
forEachOrdered
diesen Code zu verwenden?flatMap
). Es kann bestellt werden, daher muss es in derselben Reihenfolge in den resultierenden Stream gestellt werden.Stream.of("a", "b", "c").flatMap(s -> Stream.of("1", "2", "3").map(s::concat)).spliterator().hasCharacteristics(Spliterator.ORDERED)
gibt true zurück, daher muss die Reihenfolge für den resultierenden Stream bestimmt werden. Wenn Sie der Meinung sind, dass die JDK-Dokumentation dies ausdrücklich erwähnen sollte, können Sie einen Fehler einreichen.forEach()
Methode führt eine Aktion für jedes Element dieses Streams aus. Bei parallelen Streams garantiert diese Operation nicht, dass die Reihenfolge des Streams beibehalten wird.forEachOrdered()
Die Methode führt für jedes Element dieses Streams eine Aktion aus, um sicherzustellen, dass jedes Element in der Reihenfolge der Begegnung für Streams mit einer definierten Reihenfolge der Begegnung verarbeitet wird.Nehmen Sie das folgende Beispiel:
Ausgabe:
quelle