java - Collections.sort没有编译时错误

标签 java sorting collections comparable

Collections.sort(list)Collections.sort(list,null) 之间有什么区别 我认为他们都按照自然顺序比较列表中的元素。

所以我尝试了这两个代码:

代码 1:

List<Object> list=Arrays.asList("hello",123);
Collections.sort(list);

代码2:

List<Object> list=Arrays.asList("hello",123);
Collections.sort(list,null);

后者可以编译,但前者不会给出预期的编译器错误,即类 Object 的实例不可比较。 为什么后者不会给出编译时错误。

编辑:基于下面给出的评论。我理解为什么后者不会给出编译时错误,但在运行时会抛出 ClassCastException : String无法转换为 Integer 。它是如何推断出运行时对象是 String 和 Integer 因为我的想法

public static sort(List<Object> list)  ---> Since list was of type object
{
// For instances of object in list call the compareTo method 
}

}

最佳答案

Java 的泛型类型在编译时进行检查。如果你违反了约束,你甚至无法编译。第一个方法定义为:

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

这要求 List您使用的类型是 extend Comparable ,特别是一些Comparable<X>其中 X 可能是 T 的任何父类(super class)。听起来很复杂,但在这里根本不重要(如果您对那部分感兴趣,请尝试理解 http://yzaslavs.blogspot.de/2010/07/generics-pecs-principle-step-by-step.html )。 List<Object>已经与第一部分不匹配。 Object没有实现任何Comparable 。 => 编译器说不。

第二个定义为

<T> void sort(List<T> list, Comparator<? super T> c)

不再需要 List 的类型有任何特殊属性。任何T都可以。唯一的要求是您可以提供 Comparator 的实现能够对 T 或父类(super class)型进行排序。 null就像一个 clown ,适合任何东西。即使使用 null 可能是错误的,编译器也不会提示。您确实在运行时看到了问题。

<小时/>

原因

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at java.lang.Integer.compareTo(Integer.java:52)
    at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
    at java.util.Arrays.sort(Arrays.java:537)
    at java.util.TimSort.sort(TimSort.java:178)
    at java.util.TimSort.sort(TimSort.java:173)
    at java.util.Arrays.sort(Arrays.java:659)
    at java.util.Collections.sort(Collections.java:217)
    at Main.main(Main.java:9)

在“TimSort.java:178”处确实如此

static <T> void  sort(T[] a, int lo, int hi, Comparator<? super T> c) {
    if (c == null) {
        Arrays.sort(a, lo, hi);
        return;
    }

它会像您的第一次调用一样回归到自然排序。然而这只是一个Object[]到那时,没有什么可以保证类型实际上是可比较的。它只是简单地转换类型,并且根据您的运气和 Integer.compareTo( ) 或 String.compareTo( ) 中列表的内容而失败,因为这些方法需要它们自己的类型。

关于java - Collections.sort没有编译时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26627934/

相关文章:

java - 迭代列表时跳过第一项

Java : How to create a function that can only accept object which is an Interface?

javascript - 下划线多重排序

javascript - 如何根据一个(字符串和数字)对三个(更多)数组进行排序

java - 从集合中删除 N 个元素

java - 如何消除 Guava MultiMap 值中的重复项?

java - 无法用Map、ObjectMapper解析Json

Java - 具有 2 条腿 Oauth 的 Google Calendar API v3 配额

python-3.x - Pandas 按值和索引对 DF 进行排序

java - 创建可执行 jar 文件时出现问题