2010-08-17 26 views
5
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é esto arroja un ClassCastException?¿Por qué no funciona TreeSet.contains()?

+0

la Excepción debería tener más información de lo que salió mal ... casi siempre es una buena idea imprimir la Excepción y el seguimiento de la pila (simplemente agregue 'cce.printStackTrace()' dentro del bloque catch) –

Respuesta

8

Al crear instancia TreeSet sin un comparador explícito, espera que los elementos insertados implementen Comparable, pero Class no implementa esta interfaz.

para fijar, 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); 
+0

+1 para dar la comparador, aunque hubiera usado compareToIgnoreCase() ;-) – cadrian

+3

@candrian - Gracias por la votación. pero ¿cómo es que ignorarías el caso? Los nombres de clase no distinguen entre mayúsculas y minúsculas en java, y el nombre (como se da en la fuente) es lo que se almacena dentro del archivo de clase. – mdma

3

TreeSet es un conjunto ordenado, por lo que cualquier elemento que inserte debe implementar Comparable (a menos que especifique un Comparator personalizado). Class no.

Si no necesita el pedido, siempre puede usar un conjunto desordenado como HashSet. De lo contrario, tendrás que hacer tu propio pedido.

Desde el Javadoc (el énfasis es mío):

aplicación Un NavigableSet basado en un TreeMap. Los elementos se ordenan usando su orden natural, o por un comparador provisto en la creación del conjunto tiempo, dependiendo de qué constructor se use .

Esta implementación proporciona coste de tiempo de registro (n) garantizado para las operaciones básicas (agregar, eliminar y contiene).

Tenga en cuenta que el orden mantenida por un conjunto (si no se proporciona una explícita comparador) debe ser consistente con es igual si se va a correctamente implementar la interfaz Set. (Ver Comparable o Comparator para una definición precisa del consistentes con es igual a.) Esto es así porque el interfaz conjunto se define en términos de la operación es igual, pero una instancia TreeSet realiza todos los elementos comparaciones utilizando su compareTo (o comparar), por lo que dos elementos que se consideran iguales por este método son, desde el punto de vista del conjunto, iguales. El comportamiento de un conjunto está bien definido incluso si su orden es incoherente con igual; simplemente no obedece el contrato general de la interfaz Set.

Consulte también: Comparator

0

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 usa un HashSet, todo está bien.

1

cita en bloque ¿Por qué este lanzar una ClassCastException?

Fue debido a la implementación de TreeMap, el TreeSet que está basado en un juego de claves de TreeMap.

java.lang.Class no implementa la interfaz java.lang.Comparable, por lo que emitirá una excepción de ClassCastException.

Cuestiones relacionadas