por - ordenar listas doblemente enlazadas java
¿Por qué el siguiente código ordena la Lista de objetos? (5)
¿Podría explicar por qué el siguiente código compila e imprime [1, 2, 3, 4], como se esperaba? Estoy usando Java 8.
List nums = Arrays.asList(4, 3, 2, 1);
Collections.sort(nums);
System.out.println(nums);
Según tengo entendido, aquí se crean cuatro instancias de Integer. Cada entrada de la lista contiene una referencia de objeto a una instancia de Integer. Dado que la clase Objeto no implementa la interfaz Comparable, entonces Collections.sort debería lanzar ClassCastException o algo así porque no puede convertir referencias de Objeto a referencias Comparables.
¿Podría por favor indicar lo que me estoy perdiendo?
Aunque esté utilizando un entero nativo, el autobox lo convertirá automáticamente a java.lang.Integer (que implementa comparable). http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html
Con 1,2,3,4 estás creando literales int
. Al pasarlos a asList(T... a)
, se encajonan en objetos Integer
que implementa Comparable
( public final class Integer extends Number implements Comparable<Integer>
), por lo que puede ordenarlos.
Actualizar
Comentario: Sí, pero la Lista se declara como Lista, por lo que es el sinónimo de List<Object>
, no List<Integer>
, y Object
no implementa Comparable
.
Respuesta: No especifica un tipo genérico para la lista y el método Collections.sort()
solo comprueba si la clase del objeto se extiende Comparable
. Si la lista no tiene ningún tipo, su compilador solo debería darle una advertencia y todo debería funcionar bien ya que los Integer
son comparables.
El código fuente del método de clasificación.
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]);
}
}
Actualizar
Ejecute este fragmento de código para ver qué sucede si la clase no implementa 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);
}
}
¡La conversión a Comparable
que se realiza en la línea 290 de ComparableTimSort.class
fallará!
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)
En realidad es un problema de casting. Inicialmente cree una matriz de enteros y luego la convertirá en lista. Espero que este sea de utilidad para usted.
Integer[] number=new Integer[]{4,3,2,1};
Collections.sort(Arrays.asList(number));
System.out.println(Arrays.asList(number));
Hay una gran diferencia entre el tipo de referencia y el tipo real de un objeto al que apunta.
Integer i = 42;
Object o = i;
System.out.println(i.getClass());
System.out.println(o.getClass());
Salida:
class java.lang.Integer
class java.lang.Integer
Tanto i
como o
apuntan a un objeto (o valor) cuyo tipo de tiempo de ejecución es siempre Integer. Señalar el objeto utilizando una referencia de un tipo más general no afecta de ninguna manera a sus propiedades o comportamiento. Así es como funciona el polimorfismo en Java.
Por lo tanto, estas dos tareas funcionan:
Comparable<Integer> c1 = i;
Comparable<Integer> c2 = (Comparable<Integer>) o;
La pieza que falta aquí es el borrado de tipo.
Java compila a bytecode JVM, y JVM bytecode no tiene ningún concepto de genéricos. Entonces, en tiempo de ejecución, una List
es exactamente lo mismo que una List<Comparable>
o una List<Object>
. Si su código alguna vez contenía esa información (que su código no contiene), entonces se borra cuando se compila su código.
Esto significa que en el tiempo de ejecución, no hay diferencia entre un List<Object>
y un List<Comparable>
, aparte de los elementos reales que contienen (como consecuencia, también significa que si su List
no contiene elementos, entonces no hay manera de diciendo qué tipo de List
debía ser).
Collections.sort
puede ordenar cualquier List
cuyos elementos implementen todos los Comparable
, y son comparables entre sí. Dado que su List
contiene Integer
, que implementan Comparable
, Collections.sort
puede ordenarla.
Tal vez de manera confusa, esto no es cierto para matrices, por razones históricas. Comparable[]
y Object[]
son tipos completamente diferentes. En principio, esto significa que los métodos de clasificación de matrices de Java podrían negarse a ordenar las matrices Object[]
, como cabría esperar. En la práctica no lo hacen, y Arrays.sort
acepta matrices Object[]
, de forma análoga a Collections.sort
.