2014-10-29 109 views
0

Collections.sort(list)Collections.sort(list,null) 有什么区别我推测他们都按照自然顺序比较列表中的元素。Collections.sort没有编译时间错误

所以,我想这两个代码:

CODE 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。它是如何推断,运行对象是字符串和整数的,因为我觉得

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

}

+1

'null'是一个有效的比较器。尝试运行它虽然... – Reimeus 2014-10-29 10:31:31

+0

在运行它给出ClassCastException - java.lang.String不能转换为java.lang.Integer – user2653926 2014-10-29 10:32:27

回答

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) 

两种不同的方法现在涉及到运行classcast问题的问题。

Java将您的列表转换为数组以在后台执行排序。如果您的Comparator为空,则java会将该元素投射到Comparable进行排序。幸运的是,您列表中的两个元素(String and Integer)都实施了Comparable。所以在这里没有例外。

您的列表中只有两个元素(2 < 7 7是插入阈值),所以java只是简单地进行插入排序。以整数为参数,并以字符串作为参数调用compareTo()方法。这里java将参数转换为Integer,以便它可以进行比较。正如你所看到的,String不能投到Integer,你有这个例外。

+0

你的回答非常令人满意。只是怀疑这行java会将元素转换为Comparable进行排序。是否使用getClass方法在运行时确定这些元素 – user2653926 2014-10-29 11:08:07

+0

不,如果您检查代码,java只会执行'((Comparable)dest [j-1])。compareTo(dest [j])> 0; j - )'将您的元素转换为“Comparable”。而你的classcastEx没有在这里发生。 @ user2653926 – Kent 2014-10-29 11:13:05

+0

你摇滚哥们:) – user2653926 2014-10-29 11:15:33

0
> what is null? 

根据JSL -

还有一个特殊的空类型,类型表达式null, 其中没有名字。因为空类型没有名称,所以不可能 声明空类型的变量或转换为空类型。 空引用为null 类型的表达式的唯一可能的值。空引用总是可以转换为任何引用类型。在 实践中,程序员可以忽略null类型,只是假装 那空只是一个特殊的文本,可以是任何参考 类型。

null可以是任何类型的引用,以便它可以是Comparator参考为好,这就是为什么编译器接受Collections.sort(list,null);

凡为Collections.sort(list,new Object());给出编译时异常。


在比较检查时compareTo方法将被称为凡在Integer.compareTo方法它产生ClassCastException

+0

请检查编辑 – user2653926 2014-10-29 10:46:33

+0

如果列表有元素的对象类型,然后如何整数。 compareTo被称为 – user2653926 2014-10-29 10:56:30

+0

在内部调用'margeSort'来排序元素,[在这里找到](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util /Arrays.java#Arrays.mergeSort%28java.lang.Object%5B%5D%2Cjava.lang.Object%5B%5D%2Cint%2Cint%2Cint%29) – 2014-10-29 10:59:17

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。 =>编译器说不。

第二个被定义为

<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) 

是,在 “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()中的列表内容,因为这些方法需要它们自己的类型。