Zadajesz złe pytanie. Pytasz o sequential
a parallel
podczas gdy chcesz przetwarzać pozycje w kolejności , więc musisz zapytać o zamówienie . Jeśli masz uporządkowany strumień i wykonujesz operacje gwarantujące utrzymanie kolejności, nie ma znaczenia, czy strumień jest przetwarzany równolegle czy sekwencyjnie; realizacja utrzyma porządek.
Uporządkowana właściwość różni się od równoległej i sekwencyjnej. Np jeśli zadzwonisz stream()
na zasadzie HashSet
strumień będzie nieuporządkowana podczas wywoływania stream()
na ciągu List
zwraca nakazał strumienia. Pamiętaj, że możesz zadzwonić, unordered()
aby zwolnić zamówienie i potencjalnie zwiększyć wydajność. Gdy strumień nie ma już uporządkowania, nie ma możliwości przywrócenia kolejności. (Jedynym sposobem na przekształcenie nieuporządkowanego strumienia w uporządkowany jest wywołanie sorted
, jednak wynikowa kolejność niekoniecznie jest pierwotną kolejnością).
Zobacz także sekcję „Zamawianie” w java.util.stream
dokumentacji pakietu .
Aby zapewnić utrzymanie porządku w całej operacji strumienia, musisz przestudiować dokumentację źródła strumienia, wszystkie operacje pośrednie i działanie terminala pod kątem tego, czy utrzymują porządek, czy nie (lub czy źródło ma uporządkowanie w pierwszym miejsce).
Może to być bardzo subtelne, np. Stream.iterate(T,UnaryOperator)
Tworzy uporządkowany strumień, podczas gdy Stream.generate(Supplier)
tworzy nieuporządkowany strumień. Zwróć uwagę, że popełniłeś również częsty błąd w swoim pytaniu, ponieważ nie utrzymuje kolejności. Musisz użyć, jeśli chcesz przetwarzać elementy strumienia w gwarantowanej kolejności.forEach
forEachOrdered
Więc jeśli twoje list
pytanie rzeczywiście ma wartość a java.util.List
, jego stream()
metoda zwróci uporządkowany strumień i filter
nie zmieni kolejności. Więc jeśli wywołasz list.stream().filter() .forEachOrdered()
, wszystkie elementy będą przetwarzane sekwencyjnie w kolejności, podczas gdy dla list.parallelStream().filter().forEachOrdered()
elementów mogą być przetwarzane równolegle (np. Przez filtr), ale akcja terminala będzie nadal wywoływana w kolejności (co oczywiście zmniejszy korzyści z równoległego wykonania) .
Jeśli na przykład używasz operacji takiej jak
List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());
cała operacja może skorzystać na równoległym wykonaniu, ale wynikowa lista zawsze będzie we właściwej kolejności, niezależnie od tego, czy używasz strumienia równoległego, czy sekwencyjnego.
List<>
że zachowam porządek, ale czy takCollection<>
?Set
Zwykle nie, chyba że jest toSortedSet
lubLinkedHashSet
. Widoki kolekcjiMap
(keySet()
,entrySet()
ivalues()
) dziedzicząMap
zasady, tj. Są uporządkowane, gdy mapa jestSortedMap
lubLinkedHashMap
. Zachowanie jest określane przez cechy zgłaszane przez rozdzielacz kolekcji .default
RealizacjaCollection
nie zgłaszaćORDERED
charakterystykę, więc jest to nieuporządkowana, chyba że zostaną zamienione.forEachOrdered
różni się to tylko odforEach
korzystania ze strumieni równoległych - ale dobra praktyka, aby używać go mimo wszystko podczas zamawiania, na wypadek gdyby metoda gotowania na parze kiedykolwiek się zmieniła ...W skrócie:
Kolejność zależy od struktury danych źródłowych i operacji na strumieniu pośrednim. Zakładając, że używasz a
List
przetwarzanie powinno zostać zamówione (ponieważfilter
nie zmieni tutaj kolejności).Więcej szczegółów:
Sekwencyjne vs równoległe vs nieuporządkowane:
Javadocs
Zamawianie strumienia:
Javadocs
źródło