Mastering Lambdas by Maurice Naftalin, Ch6 - Stream Performance.
There is explanation about the different characteristics of streams at the different stages of execution(intermediate & terminal). For eg.
Stream.of(8,3,5,6,7,4)//ORDERED, SIZED
.filer(i->i%2==0) // ORDERED
.sorted() // ORDERED, SORTED
.distinct() // DISTINCT, ORDERED, SORTED
.map(i->i+1) // ORDERED
.unordered(); //none
What was confusing to me was explanation of SORTED characteristics :
"Stream elements may have been sorted in other orders if a Comparator has been defined and used for the purpose, but such streams do not have the SORTED characteristic."
Why if the custom comparator is provided for the implementation of Sorted Data Structure(SortedMap in above case) the framework would not consider creating streams with SORTED characteristic?
Flown is absolutely correct in his comment. SORTED
is only reported for natural order and this has been debated before. First this is even internally used as a flag called: isNaturalSort
:
/**
* Sort using natural order of {@literal <T>} which must be
* {@code Comparable}.
*/
OfRef(AbstractPipeline<?, T, ?> upstream) {
super(upstream, StreamShape.REFERENCE,
StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
this.isNaturalSort = true;
The same flag isNaturalSort
is set to false
when used via sorted(CustomComparator)
.
This is an internal details and it seems that the jdk developers did not find useful to implemented it as such - there was probably nothing to do with it that could be really useful. But this might change...
There is at least one flaw here still. Imagine a class like this:
static class User implements Comparable<User> {
private final int id;
public User(int id) {
super();
this.id = id;
}
public int getId() {
return id;
}
@Override
public int compareTo(User usr) {
return 42; // don't do this
}
}
And some stream operations:
Stream<User> byId = Stream.of(new User(12), new User(10))
.sorted(Comparator.comparing(User::getId));
System.out.println(byId.spliterator().hasCharacteristics(Spliterator.SORTED));
Stream<User> natural = Stream.of(new User(12), new User(10))
.sorted(Comparator.naturalOrder());
System.out.println(natural.spliterator().hasCharacteristics(Spliterator.SORTED));
Stream<User> plain = Stream.of(new User(12), new User(10)).sorted();
System.out.println(plain.spliterator().hasCharacteristics(Spliterator.SORTED));
The first two report false
, but the last one reports true
; which is at least weird.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With