Stream intermediate operations ordering
java, java-8, java-stream
Solution
Your question arose because you are mapping from one type to the same type. If you think about the formal operations you are performing, it becomes clear that there is no way to change the order of the specified operations:
- you map items of a `Stream<A>` to an arbitrary type `B` creating a `Stream<B>`
- you apply a `Filter<B>` on the result of the first mapping
- you map the filtered `Stream<B>` to an arbitrary type `C` creating a `Stream<C>`
- you collect the items of type `C` into a `List<C>`
Looking at these formal steps it should be clear that there is no way to change the order of these steps due to the type compatibility requirements.
The fact that in your special case all three types happen to be `String` does not change the logic of how the `Stream`s work. Keep in mind that the actual types you are using for the type parameters are erased and do not exist at runtime.
The `Stream` implementation may coerce operations where it is useful, e.g. performing a `sorted` and `distinct` in one go but this requires that both operations are requested on the same items and `Comparator`. Or simply said, internal optimizations must not change the semantics of the requested operations.
Problem
Is there a guarantee that, when working with a stream, intermediate operations will be executed in program order? I suspect it is the case or it would lead to very subtle bugs but I could not find a definite answer. Example: ``` List<String> list = Arrays.asList("a", "b", "c"); List<String> modified = list.parallelStream() .map(s -> s + "-" + s) //"a-a", "b-b", "c-c" .filter(s -> !s.equals("b-b")) //"a-a", "c-c" .map(s -> s.substring(2)) //"a", "c" .collect(toList()); ``` Is this guaranteed to always return `["a", "c"]` or `["c", "a"]`? (if the last map operation is executed before the first map operation, that could throw an exception - similarly if the filter is executed after the second map operation, "b" will be retained in the final list)