Spliterator SORTED characteristic behaviour

45 Views Asked by At

Spliterator interface defines a number of characteristics:

A Spliterator also reports a set of characteristics() of its structure, source, and elements from among ORDERED, DISTINCT, SORTED, SIZED, NONNULL, IMMUTABLE, CONCURRENT, and SUBSIZED.

Let's have a look at Sliterator#SORTED

Characteristic value signifying that encounter order follows a defined sort order.

Now let's have a look at some examples:

List.of(1,2,3,4,5).stream().spliterator().hasCharacteristics(Spliterator.SORTED)
$1 ==> false

the stream is not sorted, so Spliterator.SORTED should be false.

Let's sort the stream:

List.of(1,2,3,4,5).stream().sorted().spliterator()
                           .hasCharacteristics(Spliterator.SORTED)
$2 ==> true

The stream is sorted, Spliterator.SORTED should be true, no surprises here.

Let's finally sort the stream, but using a custom Comparator.

List.of(1,2,3,4,5).stream().sorted((a,b) -> a.compareTo(b))
                  .spliterator().hasCharacteristics(Spliterator.SORTED)
$3 ==> false

And I am completely lost here. Why Spliterator.SORTED is false in this case? The stream is sorted by with a custom comparator: .sorted((a,b) -> a.compareTo(b)), but SORTED flag is false. This seems illogical to me.

Let's image the following situation:

  List.of(1,2,3,4).stream()
1:                .sorted() // SORTED flag is set to true
2:                .filter(i -> i % 2 == 0) // Operation which doesn't reset SORTED
3:                .sorted() // can be ignored
4:                .forEach(System.out::println)

there are 3 intermediate operations in the stream pipeline: two sorted and filter. On line 1: stream is sorted, on line 2: the stream is filtered and Spliterator.SORTED is still true. This means that on the sorted operation on line 3: can be ignored (has been already sorted on line 1 and SORTED flag is true.

However when sorted with comparator is used -> every call to sorted will be executed even if compatator is the same:

List.of(1,2,3,4).stream()
                .sorted(Comparator.reverseOrder()) // SORTED flag is not affected
                .filter(i -> i % 2 == 0)
                .sorted(Comparator.reverseOrder()) // will be sorted one more time
                .forEach(System.out::println)

It might be that I misunderstood the javadocs, but still this seems strange and illogical.

0

There are 0 best solutions below