[英]Why does the following code sort the List of objects?
Could you please explain why the following code compiles and prints [1, 2, 3, 4], as expected. 你能否解释为什么下面的代码按预期编译和打印[1,2,3,4]。 I'm using Java 8.
我正在使用Java 8。
List nums = Arrays.asList(4, 3, 2, 1);
Collections.sort(nums);
System.out.println(nums);
As I understand, four Integer instances is created here. 据我所知,这里创建了四个Integer实例。 Each list entry contains an Object reference to an Integer instance.
每个列表条目都包含对Integer实例的Object引用。 Since the Object class doesn't implement the Comparable interface, then Collections.sort should throw ClassCastException or something like this because it cannot cast Object references to Comparable references.
由于Object类没有实现Comparable接口,因此Collections.sort应该抛出ClassCastException或类似的东西,因为它无法将Object引用强制转换为Comparable引用。
Could you please point out what I'm missing? 你能指出我错过了什么吗?
With 1,2,3,4 you are creating int
literals. 使用1,2,3,4,您将创建
int
文字。 While passing them to asList(T... a)
they get boxed into Integer
objects which implements Comparable
( public final class Integer extends Number implements Comparable<Integer>
), so you can sort them. 在将它们传递给
asList(T... a)
它们被装入Integer
对象,这些对象实现Comparable
( public final class Integer extends Number implements Comparable<Integer>
),因此您可以对它们进行排序。
Update 更新
Comment: Yes, but the List is declared as List, so it's the synonym to List<Object>
, not List<Integer>
, and Object
doesn't implement Comparable
. 注释:是的,但List被声明为List,因此它是
List<Object>
的同义词,而不是List<Integer>
,而Object
不实现Comparable
。
Answer: You do not specify a generic type for the list and the Collections.sort()
method only checks if the object's class extends Comparable
. 答:您没有为列表指定泛型类型,
Collections.sort()
方法仅检查对象的类是否扩展Comparable
。 If the list has no type, your compiler should only give you a warning and everything should work fine since Integer
's are comparable. 如果列表没有类型,你的编译器应该只给你一个警告,一切都应该正常工作,因为
Integer
是可比的。
The source code of the sort method 排序方法的源代码
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]);
}
}
Update 更新
Execute this piece of code to see what happens if the class does not implements Comparable
. 执行这段代码,看看如果类没有实现
Comparable
会发生什么。
public class Test
{
public static void main(String[] args)
{
List objs = new ArrayList<>();
objs.add(new Test());
objs.add(new Test());
Collections.sort(objs);
}
}
The cast to Comparable
which is done in Line 290 of ComparableTimSort.class
will fail! 在
Comparable
第290行中完成的ComparableTimSort.class
将失败!
Exception in thread "main" java.lang.ClassCastException: src.Test cannot be cast to java.lang.Comparable
at java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
at java.util.ComparableTimSort.sort(Unknown Source)
at java.util.ComparableTimSort.sort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at src.Test.main(Test.java:14)
There is a big difference between type of a reference and actual type of an object it points to. 引用的类型与它指向的对象的实际类型之间存在很大差异。
Integer i = 42;
Object o = i;
System.out.println(i.getClass());
System.out.println(o.getClass());
Output: 输出:
class java.lang.Integer
class java.lang.Integer
Both i
and o
point to an object (or value) whose runtime type is always Integer. i
和o
指向运行时类型始终为Integer的对象(或值)。 Pointing to the object using a reference of a more general type doesn't affect its properties or behaviour in any way. 使用更一般类型的引用指向对象不会以任何方式影响其属性或行为。 This is how polymorphism works in Java.
这就是多态在Java中的工作原理。
Therefore, both of these assignments work: 因此,这两项任务都有效:
Comparable<Integer> c1 = i;
Comparable<Integer> c2 = (Comparable<Integer>) o;
Even though you are using native integer, the autobox will automatically convert it to java.lang.Integer (which implements comparable). 即使您使用的是原生整数,autobox也会自动将其转换为java.lang.Integer(实现可比较)。 http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html
http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html
Actually it is a casting problem. 实际上这是一个铸造问题。 Initially create a integer array and then you have converted into list.
最初创建一个整数数组,然后您已转换为列表。 I hope this one is helpful for you.
我希望这个对你有所帮助。
Integer[] number=new Integer[]{4,3,2,1};
Collections.sort(Arrays.asList(number));
System.out.println(Arrays.asList(number));
The missing piece here is type erasure. 缺少的部分是类型擦除。
Java compiles to JVM bytecode, and JVM bytecode has no concept of generics. Java编译为JVM字节码,JVM字节码没有泛型概念。 So at runtime, a
List
is precisely the same as a List<Comparable>
or a List<Object>
. 因此,在运行时,
List
与List<Comparable>
或List<Object>
完全相同。 If your code ever contained that information (which your code doesn't), then it is erased when your code is compiled. 如果您的代码曾经包含该信息(您的代码没有),那么在编译代码时它将被删除。
This means that at runtime, there's no difference between a List<Object>
and a List<Comparable>
, other than the actual elements they contain (as a consequence, it also means that if your List
contains no elements, then there's no way of telling what sort of List
it was meant to be). 这意味着在运行时,
List<Object>
和List<Comparable>
之间没有区别,除了它们包含的实际元素(因此,它也意味着如果你的List
包含任何元素,那么就没有办法了告诉它是什么类型的List
)。
Collections.sort
is able to sort any List
whose elements all implement Comparable
, and are comparable with each other. Collections.sort
能够对其元素全部实现Comparable
并且彼此具有Comparable
任何List
进行排序。 Since your List
contains Integer
s, which implement Comparable
, Collections.sort
is able to sort it. 由于
List
包含实现Comparable
Integer
,因此Collections.sort
能够对其进行排序。
Perhaps confusingly, this isn't true of arrays, for historical reasons. 也许是令人困惑的,出于历史原因,这不是阵列的真实情况。
Comparable[]
and Object[]
are completely different types. Comparable[]
和Object[]
是完全不同的类型。 In principle, this means that Java's array sorting methods could refuse to sort Object[]
arrays, as you might expect. 原则上,这意味着Java的数组排序方法可能会拒绝对
Object[]
数组进行排序,正如您所期望的那样。 In practice they do not, and Arrays.sort
accepts Object[]
arrays, analogously to Collections.sort
. 实际上它们没有,
Arrays.sort
接受Object[]
数组,类似于Collections.sort
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.