Lista alla conversione TreeSet produce: “java.lang.ClassCastException: MyClass non può essere gettato a java.lang.Comparable”
-
22-09-2019 - |
Domanda
List<MyClass> myclassList = (List<MyClass>) rs.get();
TreeSet<MyClass> myclassSet = new TreeSet<MyClass>(myclassList);
Non capisco il motivo per cui questo codice genera questo:
java.lang.ClassCastException: MyClass cannot be cast to java.lang.Comparable
MyClass non implementa Comparable. Voglio solo usare un set per filtrare gli elementi unici della Lista dato che il mio elenco contiene i duplicati unncessary.
Soluzione
Lo MyClass implements Comparable<MyClass>
o qualcosa di simile?
Se no, allora ecco perché.
Per TreeSet
, hai a fare l'elementi Comparable
, o fornire un Comparator
. In caso contrario, TreeSet
non può funzionare in quanto non saprebbe come ordinare gli elementi.
Ricordate, TreeMap implements SortedSet
, quindi deve sapere come ordinare
gli elementi di un modo o nell'altro.
Si dovrebbe familiarizzare con come l'implementazione di Comparable
definisce ordinamento naturale per oggetti di un dato tipo.
L'interfaccia definisce un metodo, compareTo
, che deve restituire un intero negativo, zero o un numero intero positivo se questo oggetto è inferiore, uguale o superiore al altro oggetto rispettivamente.
Il contratto di richiede che:
-
sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
- è transitiva:
x.compareTo(y)>0 && y.compareTo(z)>0
implicax.compareTo(z)>0
-
x.compareTo(y)==0
implica chesgn(x.compareTo(z)) == sgn(y.compareTo(z))
per tuttiz
Inoltre, raccomanda che:
-
(x.compareTo(y)==0) == (x.equals(y))
, vale a dire "coerente conequals
Questo può sembrare molto da digerire in un primo momento, ma in realtà è abbastanza naturale con come si definisce ordinamento totale.
Se i vostri oggetti non possono essere ordinate in un modo o in un altro, poi un TreeSet
avrebbe alcun senso. Si consiglia di utilizzare un HashSet
invece, che hanno i propri contratti. Si rischia di essere richiesto di @Override hashCode()
e equals(Object)
come appropriato per il tipo (vedi: eguali Override e hashCode in Java )
Altri suggerimenti
Se non si passa un Comparator
esplicito a un TreeSet
, cercherà di confrontare gli oggetti (dal ammesso che sono Comparable
). E se non sono Comparable
, non può confrontarli, quindi questa viene generata un'eccezione!
TreeSets
sono allineati set e richiedono sia oggetti da Comparable
o un Comparator
da passare in per determinare come ordinare gli oggetti nel Set
.
Se si desidera solo il set per rimuovere i duplicati, usato un HashSet
, anche se che provvederà a mischiare l'ordine degli oggetti restituiti dal Iterator
in modi che sembrano casuali.
Ma se si desidera mantenere l'ordine in qualche modo, utilizzare LinkedHashSet
, che sarà almeno di preservare l'ordine di inserimento della lista.
TreeSet
è appropriata solo se avete bisogno della Set
ordinato, sia per l'implementazione del Oggetto della Comparable
o da un Comparator
personalizzato passata al costruttore TreeSet's
.