我正在尝试将两个'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));
然后它成功了。为什么会发生异常,我该如何解决?
答案 0 :(得分:23)
Employee
必须实施Comparable
,或者在创建provide a comparator时需要TreeSet
。
这在SortedSet
的文档中有详细说明:
插入到有序集合中的所有元素必须实现
Comparable
接口(或由指定的比较器接受)。此外,所有这些元素必须具有可比性:e1.compareTo(e2)
(或comparator.compare(e1, e2)
)不得为有序集合中的任何元素ClassCastException
和e1
抛出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)
TreeSet
是SortedSet
的实现。您可以让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