如果使用自定义Comparator创建,则为SortedMap生成的流的流特征可能不会被分类

由Maurice Naftalin掌握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特征的解释:

“如果比较器已被定义并用于此目的,则流元素可能已按其他顺序排序,但此类流不具有SORTED特征。”

为什么如果提供自定义比较器来实现排序数据结构(在上面的情况下为SortedMap),框架将不考虑创建具有SORTED特性的流?

飞行在他的评论中绝对正确。 SORTED仅针对自然顺序进行报告,此前一直有争议。 首先,这甚至在内部用作名为: isNaturalSort的标志:

 /** * Sort using natural order of {@literal } which must be * {@code Comparable}. */ OfRef(AbstractPipeline upstream) { super(upstream, StreamShape.REFERENCE, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED); this.isNaturalSort = true; 

通过sorted(CustomComparator)使用时,相同的标志isNaturalSort设置为false

这是一个内部细节,似乎jdk开发人员没有找到有用的实现它 – 可能与它无关可能真的很有用。 但这可能会改变……

这里至少还有一个漏洞。 想象一下这样的一个类:

 static class User implements Comparable { 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 byId = Stream.of(new User(12), new User(10)) .sorted(Comparator.comparing(User::getId)); System.out.println(byId.spliterator().hasCharacteristics(Spliterator.SORTED)); Stream natural = Stream.of(new User(12), new User(10)) .sorted(Comparator.naturalOrder()); System.out.println(natural.spliterator().hasCharacteristics(Spliterator.SORTED)); Stream plain = Stream.of(new User(12), new User(10)).sorted(); System.out.println(plain.spliterator().hasCharacteristics(Spliterator.SORTED)); 

前两个报告是false ,但最后一个报告是true ; 这至少很奇怪。