javajava-streamunordered

Why does an unordered sequential stream always return the same thing to me when it shouldn't?


List<Integer> list = new ArrayList<>();

for (int i = 0; i < 100_000_000; i++) {
    list.add(i);
}


list.stream().unordered().limit(50_000_000).skip(25_000_000).findFirst().ifPresent(System.out::println); // 25000000 always

For sequential streams, the presence or absence of an encounter order does not affect performance, only determinism.

But no matter how many times I run this code, I always get the same result, which does not agree with the above statement. Why?


Solution

  • Unordered simply says "don't bother ordering this stream." It is there to prevent final ordering operations that are unnecessary and therefore might incur additional overhead and impact performance. An example of how this might be used would be joining different pieces of an ordered stream in a parallel operation. For an ordered stream, having to wait for certain threads to finish processing to preserve order could take longer than if the output of each thread was used as it finished.

    But as was said/implied in the comments, no operation goes out of its way to change the order of the stream unless it is specifically directed to (e.g. sort). The output of a sort operation would be marked as ordered because order preservation is required.

    Streams are initially ordered as values are placed on the stream as they are encountered.

    int ch = IntStream.range(0,2).unordered().spliterator().characteristics();
    System.out.println(ch&Spliterator.ORDERED);
    

    prints 0 so ordered bit not set

    Set's are unordered data structures so sorting forces them to be ordered.

    int ch =Set.of(1,2,3,4,5).stream().sorted().spliterator().characteristics();
    System.out.println(ch&Spliterator.ORDERED);
    

    prints 16 so ordered bit (bit 4) is set.