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

Java 如果使用自定义比较器创建,则为SortedMap生成的流的流特征可能不会被排序,java,java-8,java-stream,Java,Java 8,Java Stream,掌握Lambdas由Maurice Naftalin,Ch6-流性能 对不同执行阶段(中间和终端)的流的不同特征进行了解释。 例如 令我困惑的是对分类特征的解释: “如果比较器已定义并用于此目的,则流元素可能已按其他顺序排序,但此类流不具有排序特征。” 为什么如果为排序数据结构的实现提供自定义比较器(SORTEDMAP在上述情况下),框架不会考虑创建具有排序特征的流?代码>已排序仅针对自然顺序进行报告,这一点以前已经讨论过。首先,这甚至在内部用作一个名为:isNaturalSort: /**

掌握Lambdas由Maurice Naftalin,Ch6-流性能

对不同执行阶段(中间和终端)的流的不同特征进行了解释。 例如

令我困惑的是对分类特征的解释:

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


为什么如果为排序数据结构的实现提供自定义比较器(SORTEDMAP在上述情况下),框架不会考虑创建具有排序特征的流?代码>已排序仅针对自然顺序进行报告,这一点以前已经讨论过。首先,这甚至在内部用作一个名为:
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;
以及一些流操作:

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));
Stream byId=Stream.of(新用户(12)、新用户(10))
.sorted(Comparator.comparing(User::getId));
System.out.println(byId.spliterator().hasCharacteristics(spliterator.SORTED));
自然流=自然流(新用户(12)、新用户(10))
.sorted(Comparator.naturalOrder());
System.out.println(natural.spliterator().haspliterators(spliterator.SORTED));
Stream plain=Stream.of(新用户(12),新用户(10)).sorted();
System.out.println(plain.spliterator().hasCharacteristics(spliterator.SORTED));

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

你刚才问了两次同样的问题吗?没有,标题被错误地粘贴了,因为我认为这是两个不同的问题。我已经编辑了标题。我想他们应该把它命名为
NATURAL\u SORTED
,而不是
SORTED
。这是一个实现细节,文档中没有提及。从技术上讲,这并不“奇怪”。根本不可能检测比较器是否是
naturalOrder
one(至少,没有奇怪的破解)。所以至少。。。不幸的是,因为人们可能合理地期望
sorted()
sorted(naturalOrder())
产生相同的结果……@Marco13:这其实很简单:
comparator==comparator.naturalOrder()
。虽然这是特定于实现的,但流实现是同一JRE的一部分,该JRE具有此测试所适用的
比较器
实现…@Holger,这与我所说的hack接近-主要是因为它不包括手工制作的比较器,它按自然顺序进行比较,更不用说像
reverse(reverse(natural()))
…@Marco13:你是说
Comparator.naturalOrder()==Comparator.naturalOrder().reversed().reversed()
?这将在OpenJDK/Oracle的JRE中返回
true
。除此之外,我确实知道“我们不能覆盖所有案例的100%,因此,我们决定不支持哪怕是合理的99%”解释。我仍然不相信…@Marco13:请记住,
StreamOpFlag.IS_SORTED
不是
public
,因此,它不一致的用法不会让那些只看官方API的人感到困惑。
Spliterator
API允许报告非自然订单的
SORTED
特征,并且有一种方法允许获得实际订单。这是您得到的,例如,从
新树集(Comparator.reverseOrder()).stream().spliterator()
;它将与逆序比较器一起报告排序后的
特性。
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));