Stream characteristics for the streams generated for SortedMap may not be SORTED if created with custom Comparator

后端 未结 1 1671
傲寒
傲寒 2020-12-17 01:06

Mastering Lambdas by Maurice Naftalin, Ch6 - Stream Performance.

There is explanation about the different characteristics of streams at the different stages of execu

相关标签:
1条回答
  • 2020-12-17 02:13

    Flown is absolutely correct in his comment. SORTED is only reported for natural order and this has been debated before. First this is even internally used as a flag called: 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;
    

    The same flag isNaturalSort is set to false when used via sorted(CustomComparator).

    This is an internal details and it seems that the jdk developers did not find useful to implemented it as such - there was probably nothing to do with it that could be really useful. But this might change...

    There is at least one flaw here still. Imagine a class like this:

    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
        }
    
    }
    

    And some stream operations:

    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));
    

    The first two report false, but the last one reports true; which is at least weird.

    0 讨论(0)
提交回复
热议问题