为什么TreeSet会抛出ClassCastException?

时间:2013-04-11 07:31:03

标签: java exception collections set treeset

我正在尝试将两个'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));

然后它成功了。为什么会发生异常,我该如何解决?

6 个答案:

答案 0 :(得分:23)

Employee必须实施Comparable,或者在创建provide a comparator时需要TreeSet

这在SortedSet的文档中有详细说明:

  

插入到有序集合中的所有元素必须实现Comparable接口(或由指定的比较器接受)。此外,所有这些元素必须具有可比性:e1.compareTo(e2)(或comparator.compare(e1, e2))不得为有序集合中的任何元素ClassCastExceptione1抛出e2 。尝试违反此限制将导致违规方法或构造函数调用抛出ClassCastException

如果您不满足这些要求,排序的集合将不知道如何比较其元素并且无法运行。

答案 1 :(得分:2)

如果未设置自定义TreeSet,则

Comparable需要元素来实现Comparator接口。 HashSet使用equals / hashCode合同。

您只能在TreeSet中添加一个未实现Comparable的元素,因为它不需要与其他元素进行比较。

查看TreeMap.put(K key, V value)源代码,您将清楚地看到所有问题背后的原因(TreeSet基于TreeMap,因此源参考)。

答案 2 :(得分:1)

来自TreeSet#add(E) JavaDoc:

  

引发:ClassCastException - 如果指定的对象不能   与本集中目前的元素进行比较

基本上您需要让Employee实施Comparable或向Comparator对象提供TreeSet

如果您检查TreeMap代码,您将看到如果在Map对象中未找到比较器,它将尝试直接将密钥(您的Employee对象)转换为Comparator

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

答案 3 :(得分:0)

因此,当您使用TreeSet时,需要实现与Employee对象的Comparable接口,因为TreeSet希望保持元素的排序。

答案 4 :(得分:0)

TreeSetSortedSet的实现。您可以让Employee实施Comparable界面,也可以为Comparator提供适当的TreeSet

Set<Employee> s = new TreeSet<Employee>(new EmployeeComparator());

答案 5 :(得分:0)

//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