19

我正在尝试将两个“员工”对象添加到 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));

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

4

6 回答 6

26

要么Employee必须实现,要么Comparable您需要在创建.TreeSet

这在文档中有详细说明SortedSet

插入有序集合的所有元素都必须实现Comparable接口(或被指定的比较器接受)。此外,所有这些元素必须是相互可比的:(e1.compareTo(e2)comparator.compare(e1, e2))不能ClassCastException为任何元素e1e2排序集中的元素抛出 a。尝试违反此限制将导致有问题的方法或构造函数调用抛出ClassCastException.

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

于 2013-04-11T07:33:06.850 回答
2

TreeSet如果未设置自定义,则需要元素来实现Comparable接口。改用/合约。ComparatorHashSetequalshashCode

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

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

于 2013-04-11T07:34:17.437 回答
1

TreeSet#add(E) JavaDoc:

抛出:ClassCastException - 如果指定的对象无法与当前在此集合中的元素进行比较

基本上你需要的是让Employee实现Comparable或提供一个Comparator对象TreeSet

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

...
Comparable<? super K> k = (Comparable<? super K>) key;
...
于 2013-04-11T07:35:46.493 回答
0

TreeSet是一个实现SortedSet。您可以让Employee实现Comparable接口或提供适合Comparator您的接口TreeSet

Set<Employee> s = new TreeSet<Employee>(new EmployeeComparator());
于 2013-04-11T07:35:06.867 回答
0

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

于 2013-04-11T07:33:03.430 回答
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
于 2017-07-03T09:38:11.550 回答