¿Por qué es este código lanzando un ClassCastException y cómo evitarlo
-
19-09-2019 - |
Pregunta
Considere este código:
import java.util.*;
class jm45 implements Comparator<jm45>
{
private int x;
jm45(int input) { x = input; }
public static void main( String args[] )
{
List list = new ArrayList();
list.add(new jm45(2));
list.add(new jm45(2));
Collections.sort(list); //faulty line
}
public int compare( jm45 t1 , jm45 t2 )
{
return t1.x - t2.x;
}
}
Solución
Su clase implementa Comparator<jm45>
en lugar de Comparable<jm45>
.
A Comparator
sabe cómo comparar dos objetos - una Comparable
sabe cómo comparar con otro sí
o bien tendrá que pasar en un comparador para sort()
a utilizar (como el segundo argumento) o los valores tiene que ser comparable.
Aquí hay una versión que utiliza la interfaz Comparable
lugar:
import java.util.*;
class Test implements Comparable<Test>
{
private int x;
Test(int input)
{
x = input;
}
public static void main(String args[])
{
List<Test> list = new ArrayList<Test>();
list.add(new Test(2));
list.add(new Test(2));
Collections.sort(list);
}
public int compareTo(Test other)
{
return x - other.x;
}
}
Y aquí está una versión que utiliza la interfaz Comparator
:
import java.util.*;
class TestComparator implements Comparator<Test>
{
public int compare(Test t1, Test t2)
{
return t1.getX() - t2.getX();
}
}
class Test
{
private int x;
Test(int input)
{
x = input;
}
int getX()
{
return x;
}
public static void main(String args[])
{
List<Test> list = new ArrayList<Test>();
list.add(new Test(2));
list.add(new Test(2));
Collections.sort(list, new TestComparator());
}
}
No hay nada que parada una clase que implementa Comparator<T>
por sí mismo, pero es un poco extraño para que lo haga. Por ejemplo, normalmente no se pida una cadena a comparar otros dos entre sí - no tiene nada que ver con la propia cadena original
Otros consejos
Desde el Javadoc Collections.sort:
ordena la lista especificada en orden ascendente, de acuerdo con la ordenamiento natural de sus elementos. Todos los elementos de la lista debe implementar la interfaz Comparable . Además, todos los elementos en la lista debe ser mutuamente comparables (es decir, e1.compareTo (E2) no debe lanzar una ClassCastException para cualquier elementos e1 y e2 en la lista).
Su clase implementa Comparador, no es comparable.