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.