Perché TreeSet genera ClassCastException

Nel codice seguente sto cercando di aggiungere due oggetti dipendenti

Set s = new TreeSet(); s.add(new Employee(1001)); s.add(new Employee(1002)); 

Ma Result è java.lang.ClassCastException:

 Exception in thread "main" java.lang.ClassCastException: Employee cannot be cast to java.lang.Comparable at java.util.TreeMap.put(TreeMap.java:542) at java.util.TreeSet.add(TreeSet.java:238) at MyClient.main(MyClient.java:9) 

Ma se cambio in

 Set s = new TreeSet(); s.add(new Employee(1001)); 

O

 Set s = new HashSet(); s.add(new Employee(1001)); s.add(new Employee(1002)); 

Quindi il risultato è successo, non c’è eccezione. Non sto facendo alcuna attività di casting di class nel codice sopra. Per favore aiutami a scoprire la causa e suggeriscimi la soluzione.

O il Employee deve implementare Comparable , o è necessario fornire un comparatore durante la creazione di TreeSet .

Questo è spiegato nella documentazione di SortedSet :

Tutti gli elementi inseriti in un insieme ordinato devono implementare l’interfaccia Comparable (o essere accettati dal comparatore specificato). Inoltre, tutti questi elementi devono essere reciprocamente comparabili: e1.compareTo(e2) (o comparator.compare(e1, e2) ) non deve lanciare ClassCastException per alcun elemento e1 ed e2 nel set ordinato. I tentativi di violare questa restrizione causano il metodo incriminato o la chiamata del costruttore per il lancio di ClassCastException .

Se non si soddisfano questi requisiti, il set ordinato non saprà come confrontare i suoi elementi e non sarà in grado di funzionare.

Quindi implementare l’interfaccia Comparabile con l’object Impiegato quando è necessario quando si utilizza TreeSet, perché TreeSet desidera mantenere ordinati gli elementi.

TreeSet richiede che gli elementi siano implementabili Comparable se non è impostato un Comparator personalizzato. HashSet utilizza invece il contratto equals / hashCode.

È ansible aggiungere solo un elemento in TreeSet che non implementa Comparable perché non deve essere confrontato con altri elementi.

Dai un’occhiata ai codici sorgente di TreeMap.put(K key, V value) e vedrai chiaramente le ragioni di tutte le tue domande ( TreeSet si basa su TreeMap , da cui il riferimento sorgente).

Da TreeSet # add (E) JavaDoc:

Genera : ClassCastException – se l’object specificato non può essere confrontato con gli elementi attualmente in questo set

Fondamentalmente ciò di cui hai bisogno è consentire a Employee implementare Comparable o fornire un Comparator all’object TreeSet .

Se controlli il codice TreeMap vedrai che se il comparatore non è stato trovato all’interno dell’object Map , proverà a lanciare la chiave (l’object Employee ) direttamente su Comparator :

 ... Comparable k = (Comparable) key; ... 

TreeSet è un’implementazione di SortedSet . Puoi consentire a Employee implementare l’interfaccia Comparable o fornire un Comparator appropriato per il tuo TreeSet :

 Set s = new TreeSet(new EmployeeComparator()); 
 //class Employee public class Employee implements Comparable{ int id; Employee(int id){ this.id=id; } public int compareTo(Employee e){ //implementing abstract method. if(id>e.id){ return 1; } return 0; } //class TreeSet Set emp =new TreeSet(); Employee eobj1 = new Employee(2); Employee eobj2 = new Employee(3); emp.add(eobj1); emp.add(eobj2); for (Student ss:emp) { System.out.println(ss.rollno); } } //output: 2 // 3