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.