Encounter Order and unordered()
Which sources have an order, which ops must respect it, and what that costs in parallel.
Open this lesson in the learning hubKey points
- A
Listor an array has an encounter order. AHashSetdoes not, and never promises one. findFirst,limit,skipandtoListmust honour it, so in parallel they need coordination.forEachgives up ordering on a parallel stream.forEachOrderedkeeps it, and pays for it.unordered()says you do not care, lettingdistinctandlimitskip the bookkeeping.sorted()makes a stream ordered again, whiletoSetandgroupingByhand back unordered containers.
Example
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Integer> list = IntStream.rangeClosed(1, 8).boxed().toList();
// Ordered terminal ops keep encounter order even in parallel.
System.out.println("toList par : " + list.parallelStream().map(n -> n * 2).toList());
System.out.println("findFirst par : "
+ list.parallelStream().filter(n -> n > 3).findFirst().orElseThrow());
System.out.println("limit par : " + list.parallelStream().limit(4).toList());
// forEachOrdered keeps the order; plain forEach promises nothing in parallel.
StringBuilder strict = new StringBuilder();
list.parallelStream().forEachOrdered(strict::append);
List<Integer> loose = Collections.synchronizedList(new ArrayList<>());
list.parallelStream().forEach(loose::add);
System.out.println("forEachOrdered : " + strict);
System.out.println("forEach par : " + loose + " (order not promised)");
// A HashSet has no encounter order for anything to preserve.
Set<String> set = new HashSet<>(List.of("ada", "grace", "alan", "linus"));
System.out.println("hash set : " + set.stream().toList());
// unordered() says "I do not care", so the pipeline can skip the bookkeeping.
System.out.println("unordered : " + list.parallelStream().unordered()
.filter(n -> n % 2 == 0).collect(Collectors.toSet()));
}
}
Order is a promise the runtime pays for. Give it up on purpose, never by accident.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.