当前位置: 首页 > 面试题库 >

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

汤英豪
2023-03-14
问题内容

第六章Maurice Naftalin的精通Lambdas-流性能。

有关于在执行的不同阶段(中间和终端)的流的不同特性的解释。例如。

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 <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; 这 至少 很奇怪。



 类似资料:
  • 从这个问题 报告不可变或并发的拆分器保证不会抛出ConcurrentModificationException。当然,CONCURRENT排除了语义上的大小,但这对客户机代码没有影响。 事实上,这些特性在Stream API中没有任何用途,因此,不一致地使用它们永远不会在任何地方被注意到。 这也是为什么每个中间操作都有清除并发、不可变和非空特性的效果的原因:流实现不使用这些特性,其表示流状态的内部

  • 我正试图在一个项目中使用XML特性生成器描述符和一些非标准特性设置OpenNLP NameFinder。XML描述符支持自定义功能生成器: 但是,留档并没有提到将参数传递给特征生成器。为特征生成器的每一个稍微不同的配置创建一个新类是不可取的。另一方面,以编程方式创建特征生成器可能意味着复制大部分用于处理特征生成器设置的OpenNLP代码。在OpenNLP中使用自定义特征生成器的推荐方法是什么?

  • 问题内容: 我想用自定义排序顺序在Java中创建一个。字符串排序的键需要根据第二个字符进行排序。这些值也是字符串。 样本图: 问题答案: 您可以像这样使用自定义比较器: 样品: 请注意,这只是假设字符在索引1处有一个字符。 另外,您也可以使用以下比较: 通常,此减法“技巧”是无效的,但在这里可以正常使用,因为减法2 不会溢出。 不过,上面的and 解决方案更具可读性。

  • 此方法采用一个所有值都等于null的映射,并返回一个由相同键组成的SortedMap和新值(通过objectiveFitness获得) 步骤1.首先,我从输入映射中提取键并用相同的键构造一个新的HashMap,新的值是objectiveFitness(key)。 第二步。下一步是使用流将HashMap中的所有条目收集到带有自定义比较器的SortedMap中。 ...我发现,由于我想根据条目的自然排

  • 问题内容: 我正在处理大量旧数据(从平面文件db转换),其中字段的格式设置为输入记录的年份的最后2位,然后是4位的增量… 例如,1998年创建的第三条记录将为“ 980003”,而2004年创建的第十一条记录将为“ 040011”。 我无法更改这些值- 它们通过他们的公司存在,已经在州,客户等中注册。我知道将年份和其余年份分隔到单独的列中会很好,但这是不可能的。我什至不能真正做到“内部”,因为每一

  • 我如何用java8流式API表达这一点? 我想对流中的每个项执行itemcumer。如果没有要执行的项目,则清空操作。 我当然可以写这样的东西: 但我更愿意避免任何s。 我还考虑过在peek方法中设置一个标志,但该标志是非最终的,因此是不允许的。使用布尔容器似乎也是一种太多的变通方法。