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 cannot be converted into 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
}
}
答案 0 :(得分:2)
在编译时检查Java的泛型类型。如果违反约束,您甚至无法编译。第一种方法定义为:
<T extends Comparable<? super T>> void sort(List<T> list)
这要求您使用的List
类型为extend Comparable
,特别是某些Comparable<X>
,其中X可能是T的任何超类。听起来很复杂但不均匀这里很重要(如果您对该部分感兴趣,请尝试理解http://yzaslavs.blogspot.de/2010/07/generics-pecs-principle-step-by-step.html)。 List<Object>
已经与第一部分不匹配。 Object
未实施任何Comparable
。 =&GT;编译器说没有。
第二个定义为
<T> void sort(List<T> list, Comparator<? super T> c)
不再要求List
的类型具有任何特殊属性。任何T都会起作用。唯一的要求是您可以提供能够对T或超类型进行排序的Comparator
实现。 null
就像一个小丑,适合任何。即使使用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)
是&#34; TimSort.java:178&#34;它确实
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()中,因为这些方法需要它们自己的类型。
答案 1 :(得分:1)
Collections
//here the elements in list should impl. Comparable
Collections.sort(list)
//here we need a Comparator object, (null is Comparator obj too)
Collections.sort(list, null)
现在谈到运行时类广播问题。
Java将您的列表转换为数组以在后台进行排序。如果Comparator
为null,则java会将元素强制转换为Comparable
以进行排序。幸运的是,列表中的两个元素(String and Integer
)都实现了Comparable
。所以直到这里没有例外。
列表中只有两个元素(2 <7 7是insertionsort阈值),因此java只是简单地进行插入排序。取整数,并使用字符串作为参数调用compareTo()
方法。这里java将参数转换为Integer,以便它可以比较。正如您所见,String
无法转换为Integer
,您就会遇到此异常。
答案 2 :(得分:0)
> what is null?
根据JSL -
还有一个特殊的null类型,表达式的类型为null, 没有名字。因为null类型没有名称,所以不可能 声明null类型的变量或转换为null类型。 空引用是null表达式的唯一可能值 类型。 null引用始终可以强制转换为任何引用类型。在 实践中,程序员可以忽略null类型而只是假装 null只是一个特殊的文字,可以是任何参考 类型。
由于null
可以是任何类型的引用,因此它也可以引用Comparator
,这就是编译器接受Collections.sort(list,null);
的原因。
Collections.sort(list,new Object());
给出编译时异常的地方。
在比较时检查compareTo
方法将调用Integer.compareTo
方法生成ClassCastException
的位置。
答案 3 :(得分:0)
这两者之间没有区别,api doc中明确提到过。 请参阅Collections