如果使用自定义比较器创建,则为 SortedMap 生成的流的流特征可能不会进行排序



掌握莫里斯·纳夫塔林的 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;这至少是奇怪的。

最新更新