掌握莫里斯·纳夫塔林的 Lambdas,第 6 章 - 流性能。
有关于流在不同执行阶段(中间和终端(的不同特征的解释。例如。
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
让我感到困惑的是排序特征的解释:
"如果已定义并为此目的使用比较器,则流元素可能已按其他顺序排序,但此类流不具有SORTED特征。
为什么如果为实现排序数据结构(在上面的情况下为 SortedMap(提供自定义比较器,框架不会考虑创建具有 SORT 特征的流?
Flyown在他的评论中是绝对正确的。 SORTED
只为自然秩序而报告,这在以前已经争论过。首先,这甚至在内部用作一个标志,称为: 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;
当通过 sorted(CustomComparator)
使用时,isNaturalSort
将同一标志设置为 false
。
这是一个内部细节,似乎 jdk 开发人员发现这样实现它没有用 - 可能与它可能真正有用的无关。但这可能会改变...
这里至少还有一个缺陷。想象一下这样的班级:
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
}
}
以及一些流操作:
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));
前两个报告false
,但最后一个报告true
;这至少是奇怪的。