【问题标题】:Collections.sort implementationCollections.sort 实现
【发布时间】:2012-12-28 15:46:31
【问题描述】:

我无法理解 Collections.sort 方法的方法实现和逻辑。这是我找到的方法实现,

public static <T extends Comparable<? super T>> void sort(List<T> list) {
    Object[] a = list.toArray();
    Arrays.sort(a);
    ListIterator<T> i = list.listIterator();
    for (int j=0; j<a.length; j++) {
        i.next();
        i.set((T)a[j]);
    }
    }

首先这个方法的返回类型是void。方法签名中的&lt;T extends Comparable&lt;? super T&gt;&gt; 是什么?

这里使用 Array.sort 的目的是什么?

此外,一旦我们实现了可比较或比较器,我们编写的 compare 或 compareTo 方法逻辑在哪里需要考虑?

【问题讨论】:

  • Arrays.sort 使用修改后的快速排序算法对数组进行排序。将列表转换为数组并使用 Arrays 类中可用的 sort() 方法进行排序。然后将排序后的数组放回原始列表。所以不需要返回类型
  • @Renjith: Arrays.sort(T[]) 不使用快速排序,不稳定;它使用了 Timsort,这是一个修改过的归并排序,真的。
  • @Renjith:是的,它对 numerical 数组使用了修改后的快速排序,但对于 object arrays...
  • @LouisWasserman..非常感谢您提供的信息:-)

标签: java sorting collections


【解决方案1】:
 What is <T extends Comparable<? super T>>

这是在List&lt;T&gt; 中指定T 的类型。在 Type Inference 上阅读本教程。

【讨论】:

【解决方案2】:

首先这个方法的返回类型是void。方法签名中的 > 是什么?

是您在方法中使用的泛型类型,T 只能是实现 java.util.Comparable 的对象。

例如,如果您想将List&lt;String&gt; 传递给排序方法,它将编译为java.lang.String 实现java.lang.Comparable,但如果您传递List&lt;Animal&gt;,您将得到一个编译器错误,除非Animal 实现java.lang.comparable

【讨论】:

    【解决方案3】:

    Collections.sort 的工作方式是它实际上采用集合的底层数组,并调用 its 排序方法对实际元素进行排序。 Java 使用的排序算法是闪电般的Timsort

    该方法返回void,因为它就地对集合进行排序。也就是说,它修改你给它作为参数的集合,通过对其元素进行排序。返回排序后的副本会浪费资源。

    【讨论】:

    • 其实是调用Arrays类中的静态排序方法。数组对象在 Java 中没有自己的排序方法。此外,该集合没有(通常/必然)有一个“底层数组” - 相反,一个数组是从集合中创建的。
    【解决方案4】:

    请注意泛型出现在哪里:

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

    它基本上声明并限制泛型类型T。在这种特殊情况下,它意味着:T 必须扩展 Comparable&lt;F&gt;,其中 F 必须是 T 类型或其超类型。这意味着如果您有以下课程:

    class Animal {}
    
    class Dog extends Animal implements Comparable<Animal> {
        //...
    }
    

    您仍然可以将List&lt;Dog&gt; 传递给Collections.sort()(注意Dog 实现Comparable&lt;Animal&gt;,而不是像往常一样实现Comparable&lt;Dog&gt;)。


    Arrays.sort() 被使用是因为这是实现排序算法的地方。如果集合不是随机访问,则需要从集合到数组进行防御性复制以遵守合同并避免次优运行时。

    一些列表,例如LinkedList,随机访问(按索引)性能很差,这使得大多数排序算法非常慢(在O(n^2) 的范围内)。最好防御性地复制整个集合并对数组进行排序,因为 O(n + nlogn + n) 仍然是 O(nlogn) - 如果你得到大 O 表示法)。

    【讨论】:

    • 我仍然没有得到类 Dog extends Animal 实现 Comparable 部分?为什么我们不能有类 Dog 扩展 Animal 实现 Comparable
    • @FrankD:确实,在大多数情况下Comparable&lt;Dog&gt; 会是更好的选择。但是如果你出于某种原因实现了Comparable&lt;Animal&gt;Collections.sort() 仍然可以工作(编译)。如果它只是声明 &lt;T extends Comparable&lt;T&gt;&gt; 就不会
    • 你会在这里说哪个合同?
    【解决方案5】:

    首先这个方法的返回类型是void

    因为它是就地实施。传递给方法的列表将被排序

    &lt;T extends Comparable&lt;? super T&gt;&gt; 在方法签名中的作用是什么?

    比较扩展Comparable 接口的结果,类型为T 及其子类型。

    对象[] a = list.toArray();

    将列表转换为普通数组。

    这里使用 Array.sort 的目的是什么?

    数组排序

    i.set((T)a[j]);

    从数组中按排序顺序分配给列表元素

    【讨论】:

      猜你喜欢
      • 2017-03-21
      • 2022-07-08
      • 1970-01-01
      • 2017-12-05
      • 2020-09-22
      • 1970-01-01
      • 2018-06-05
      • 2014-11-30
      相关资源
      最近更新 更多