java - 为什么 Collections.sort 可以不带比较器而 List.sort 必须带比较器?

标签 java list sorting comparator comparable

我不明白为什么 List.sort() 没有没有比较器的版本的逻辑。

特别是我看到可以用 null 调用 List.sort:list.sort(null) ,它似乎使用自然顺序进行排序。

我注意到在我的 IDE Collections.sort() 调用 List.sort(null),所以我想知道为什么 List.sort 似乎是最近在 Java 8 中引入的没有没有比较器的简单版本,在许多病例是不需要的。

此外,我不确定在这种情况下是否最好调用 List.sort(null) 以避免额外调用,或者仍然首选调用 Collections.sort() 并避免丑陋的 null 参数。

最佳答案

域名

这是一个设计决定,混合了一些历史原因。可以添加 list.sort()但它不能确保编译时的安全,只能确保运行时的安全。对于 JDK 来说,这将是一个相当奇怪和不寻常的设计。

Collection #sort

集合,因为它可以在方法声明中指定类型边界,所以有可能强制 Comparable元素:

public static <T extends Comparable<? super T>> void sort(List<T> list)

所以该方法可以保证集合中包含Comparable元素。所以一个 Comparator不需要。

列表#sort
List不能这样做。它的泛型类型必须允许一切,你必须能够使用 List<Dog>虽然这些可能不是 Comparable .

所以如果会有 list.sort() ,则此方法需要确定列表是否为泛型类型 TComparable或不。但是这些信息只在运行时出现,我们希望它在编译时出现,但为了一个好的设计。

因为这会导致糟糕的设计,list.sort()不存在。因此,强制执行 Comparator 的额外方法这可以确保编译时的安全..

列表排序(空)

list.sort(null)而不是 list.sort()显然是 设计选择 ,在我看来不错。如前所述,这是不可能的 List以确保编译时的安全。所以唯一的选择是运行时安全,这不是那么好。

有一个 list.sort()这只有时有效并抛出异常,否则将是一个奇怪的设计选择。像list.sort(null)这样的电话但是对于任何用户来说都更清楚。特别是,更清楚的是,这将由运行时决策覆盖,而不是由编译时检查覆盖。

您可能希望更明确地表达并赋予它微不足道的 Comparator使用自然顺序:
list.sort(Comparator.naturalOrder());

这至少对读者来说会更清楚。

历史

您现在可能想知道为什么 List.sort(null) even 是一个受支持的功能以及为什么他们不要求你给它一个明确的 Comparator总是。我无法深入了解开发人员的想法,但我怀疑是历史原因。 JDK中有不少类似的例子,尤其是排序方面。

这主要是因为 Java 保持了向后兼容性。泛型是在 Java 5 中引入的,所以之前存在的所有处理容器的东西在设计时都没有考虑到类型安全。

有几个高度相关的例子:
  • Arrays#sort(Object[]) (自 Java 1.2 起)不强制 Comparable .因此,他们不得不在 Java 5 Arrays.sort(T[], Comparator) 中添加额外的重载。 , 和 List 一模一样例子。
  • 方法Collections.sort(T[], Comparator)实际接受 null为比较器。一个糟糕的设计选择,但它是在泛型尚不存在的时候做出的。所以他们不能再删除这个功能了。
  • 有趣的是,他们决定让List.sort(Comparator) ,一种新方法,也支持null .然而,在 Stream.sort(Comparator)他们没有。这是 JDK 中的一个奇怪的不一致。
  • 关于java - 为什么 Collections.sort 可以不带比较器而 List.sort 必须带比较器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61222407/

    相关文章:

    java - JButton 不工作[捕获网络流量]

    python - 基于特定元素对列表进行排序 - Python

    java - 如何解决Java Collections.sort() Comparison方法违反其一般契约异常

    c - 将合并操作的结果直接复制到辅助数组时,合并排序不起作用

    c# - 快速排序正态分布的 double

    java - 创建对对象的引用

    java - 有没有办法知道 JPanel 是否已完成加载其内容?

    java - 将 GUI 功能添加到编写 XML 文件的 Java 程序中

    r - 将列表的多个元素转换为矩阵 R

    jquery - 使用 jquery 将列表项的一部分替换为来自表单的输入