forEach vs foreach w Javie 8 Stream
Rozumiem, że te metody różnią się kolejnością wykonania, ale w całym moim teście nie mogę osiągnąć innego wykonania zlecenia.
Przykład:
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));
Wyjście:
forEach Demo
Output:AAA
Output:BBB
Output:CCC
forEachOrdered Demo
Output:AAA
Output:BBB
Output:CCC
Proszę podać przykłady, gdy 2 metody przyniosą różne wyniki.
3 answers
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));
Druga linia zawsze wyświetli
Output:AAA
Output:BBB
Output:CCC
Podczas gdy pierwsza nie jest gwarantowana, ponieważ zamówienie nie jest utrzymywane. forEachOrdered
przetwarza elementy strumienia w kolejności określonej przez jego źródło, niezależnie od tego, czy strumień jest sekwencyjny czy równoległy.
Cytowanie z forEach
Javadoc:
Zachowanie tej operacji jest jawnie nieeterministyczne. W przypadku rurociągów o równoległym strumieniu operacja ta nie gwarantuje przestrzegania spotkać się z porządkiem strumienia, gdyż uczynienie tego poświęciłoby korzyść paralelizmu.
Gdy forEachOrdered
Stany Javadoc (podkreślenie):
Wykonuje akcję dla każdego elementu tego strumienia, w porządku spotkania strumienia jeśli strumień ma zdefiniowany porządek spotkania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 13:18:29
Chociaż forEach
jest krótszy i wygląda ładniej, sugerowałbym użycie forEachOrdered
w każdym miejscu, gdzie liczy się porządek, aby to wyraźnie określić. Dla sekwencyjnych strumieni forEach
wydaje się, że respektuje kolejność, a nawet wewnętrzny kod stream API używa forEach
(dla strumienia, który jest znany jako sekwencyjny), gdzie semantycznie konieczne jest użycie forEachOrdered
! Niemniej jednak możesz później zdecydować się na zmianę strumienia na równoległy, a Twój kod zostanie uszkodzony. Również gdy używasz forEachOrdered
czytnika kodu widzi komunikat: "tu liczy się porządek". W ten sposób lepiej dokumentuje Twój kod.
Zauważ również, że dla równoległych strumieni forEach
nie tylko jest wykonywany w porządku niedetermenistycznym, ale także może być wykonywany jednocześnie w różnych wątkach dla różnych elementów(co nie jest możliwe w przypadku forEachOrdered
).
Wreszcie oba forEach
/forEachOrdered
są rzadko przydatne. W większości przypadków rzeczywiście trzeba uzyskać jakiś wynik, a nie tylko efekt uboczny, a więc operacje takie jak reduce
lub collect
powinno być bardziej odpowiednie. Wyrażanie operacji redukcji przez naturę za pomocą forEach
jest zwykle uważane za zły styl.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 13:31:28
Metoda ForEach () wykonuje akcję dla każdego elementu tego strumienia. W przypadku równoległego strumienia operacja ta nie gwarantuje utrzymania porządku strumienia.
Metoda ForEachOrdered() wykonuje akcję dla każdego elementu tego strumienia, gwarantując, że każdy element jest przetwarzany w porządku spotkania dla strumieni, które mają zdefiniowany porządek spotkania.
Weźmy poniższy przykład:
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));
Wyjście:
****forEach bez użycia parallel * * * *
Sushil mittal
****forEach with using parallel * * * *
Mihul issltat
****forEachOrdered with using parallel * * * *
Sushil mittal
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 06:59:03