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

时间:2017-06-11 16:34:46

标签: java java-8 java-stream

由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特性的流?

1 个答案:

答案 0 :(得分:7)

在他的评论中,飞行是完全正确的。 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;

通过isNaturalSort使用时,同一个标记false设置为sorted(CustomComparator)

这是一个内部细节,似乎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;这至少很奇怪。