Zadajesz złe pytanie. Pytasz o sequentiala parallelpodczas 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 HashSetstrumień będzie nieuporządkowana podczas wywoływania stream()na ciągu Listzwraca 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.streamdokumentacji 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 listpytanie rzeczywiście ma wartość a java.util.List, jego stream()metoda zwróci uporządkowany strumień i filternie 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.