¿Por qué no TreeSet.contains de trabajo ()?
-
29-09-2019 - |
Pregunta
public class Empty {
public static void main( String[] args ) {
TreeSet<Class> classes = new TreeSet<Class>();
classes.add( String.class );
String test = new String();
try{
if( classes.contains(test.getClass()) ){
System.out.println( "contains" );
}
}catch(ClassCastException cce){
System.out.println( "Expected: " + classes );
System.out.println( "But it was: " + test.getClass() );
}
}
}
¿Por qué este lanzar una ClassCastException
?
Solución
Cuando una instancia de TreeSet
sin un comparador explícita, se espera que los elementos insertada para implementar Comparable
, pero Class
no implementa esta interfaz.
Para solucionarlo, crear un comparador para Class
:
Comparator<Class> classComp = new Comparator<Class>()
{
@Override
public int compare(Class o1, Class o2)
{
return o1.getName().compareTo(o2.getName());
}
};
TreeSet<Class> classes = new TreeSet<Class>(classComp);
Otros consejos
TreeSet
es un conjunto ordenado, por lo que cualquier elemento que inserte debe implementar Comparable
(a menos que especifique un Comparator
personalizado). Class
no lo hace.
Si no es necesario el orden, siempre se puede utilizar un conjunto desordenado como HashSet . De lo contrario, tendrá que llegar a un ordenamiento de su cuenta.
Desde el Javadoc (el énfasis es mío):
Una aplicación basada en NavigableSet un TreeMap. Los elementos están clasificadas utilizando su orden natural, o por una Comparador proporciona en la creación conjunto tiempo , dependiendo de qué constructor se utiliza.
Esta aplicación ofrece costo de tiempo log (n) garantizada para el operaciones básicas (añadir, eliminar y contiene).
Tenga en cuenta que el orden mantenido por una conjunto (sea o no una explícita comparador está provisto) debe estar consistente con iguales si ha de correctamente implementar la interfaz Set. (Ver Comparable o Comparator para una definición precisa de coherente con es igual.) Esto es así porque el conjunto interfaz se define en términos de la es igual a la operación, pero un TreeSet instancia realiza todo elemento comparaciones utilizando su compareTo (o comparar método), por lo que dos elementos que se consideran iguales por este método son, desde el punto de vista del conjunto, la igualdad. El comportamiento de un conjunto está bien definido incluso si su pedido es inconsistente con iguales; simplemente no obedece las contrato general de la interfaz conjunto.
Ver también: Comparador
cita en bloque ¿Por qué esto lanzar una ClassCastException?
Fue la causa por la implementación de TreeMap, la TreeSet que es un conjunto clave de TreeMap se basa en ella.
java.lang.Class no implementa la interfaz java.lang.Comparable, por lo que arrojará una excepción de ClassCastException.
El error real es java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Comparable
. Aquí está - TreeSet impone un orden en los elementos. Si utiliza un HashSet, todo está bien.