簡體   English   中英

為什么TreeSet會拋出ClassCastException?

[英]Why does TreeSet throw a ClassCastException?

我試圖將兩個'Employee'對象添加到TreeSet:

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

但它會拋出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)

但是,如果我只向TreeSet添加一個對象:

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

或者,如果我使用HashSet:

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

然后它成功了。 為什么會發生異常,我該如何解決?

Employee必須實現Comparable ,或者在創建TreeSet時需要提供比較器

這在SortedSet的文檔中有詳細說明:

插入到有序集中的所有元素必須實現Comparable接口(或者由指定的比較器接受)。 此外,所有這些元素必須是可相互比較的: e1.compareTo(e2) (或comparator.compare(e1, e2) )不得對有序集合中的任何元素e1e2拋出ClassCastException 嘗試違反此限制將導致違規方法或構造函數調用拋出ClassCastException

如果您不滿足這些要求,則排序集將不知道如何比較其元素並且將無法運行。

如果未設置自定義Comparator TreeSet需要元素來實現Comparable接口。 HashSet使用equals / hashCode合約。

您只能在TreeSet添加一個不實現Comparable元素,因為它不需要與其他元素進行比較。

看看TreeMap.put(K key, V value)源代碼,您將清楚地看到所有問題背后的原因( TreeSet基於TreeMap ,因此是源參考)。

TreeSet #add(E) JavaDoc:

拋出 :ClassCastException - 如果指定的對象無法與此set中當前的元素進行比較

基本上你需要的是讓Employee實現Comparable或者為TreeSet對象提供一個Comparator

如果檢查TreeMap代碼,您將看到如果在Map對象中找不到比較器,它將嘗試將密鑰(您的Employee對象)直接轉換為Comparator

...
Comparable<? super K> k = (Comparable<? super K>) key;
...

因此,當您使用TreeSet時,需要實現與Employee對象的Comparable接口,因為TreeSet希望保持元素的排序。

TreeSetSortedSet一個實現。 您可以讓Employee實現Comparable接口,也可以為TreeSet提供適當的Comparator

Set<Employee> s = new TreeSet<Employee>(new EmployeeComparator());
//class Employee
    public class Employee implements Comparable<Employee>{
    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<Employee> emp =new TreeSet<Employee>();

    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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM