为什么TreeSet会抛出ClassCastException
在下面的代码我试图添加两个员工对象
Set s = new TreeSet(); s.add(new Employee(1001)); s.add(new Employee(1002));
但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)
但如果我换到。
Set s = new TreeSet(); s.add(new Employee(1001));
要么
Set s = new HashSet(); s.add(new Employee(1001)); s.add(new Employee(1002));
那么结果就是成功也没有例外。 我没有在上面的代码中进行任何类转换活动。 请帮我找出原因并建议我解决方案。
Employee
必须实现Comparable
,或者在创建TreeSet
时需要提供比较器 。
这在SortedSet
的文档中有详细说明:
插入到有序集中的所有元素必须实现
Comparable
接口(或者由指定的比较器接受)。 此外,所有这些元素必须是可相互比较的:e1.compareTo(e2)
(或comparator.compare(e1, e2)
)不得为有序集合中的任何元素e1
和e2
抛出ClassCastException
。 尝试违反此限制将导致违规方法或构造函数调用抛出ClassCastException
。
如果您不满足这些要求,则排序集将不知道如何比较其元素并且无法运行。
因此,当您使用TreeSet时,需要实现与Employee对象的Comparable接口,因为TreeSet希望保持元素的排序。
如果未设置自定义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
是SortedSet
一个实现。 您可以让Employee
实现Comparable
接口或为TreeSet
提供适当的Comparator
:
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
- JDK8 CompletableFuture.supplyAsync如何处理interruptedException
- Java – 应该在何处以及如何使用exception?
- 谷歌应用引擎HardDeadlineExceededError
- javax.persistence.NoResultException:getSingleResult()没有检索任何实体
- 处理在单独线程中抛出的exception的最佳方法是什么?
- 从日志文件中提取java堆栈跟踪的工具
- Eclipse中exception的断点 – 如何检查Exception对象?
- 字段初始化中未处理的exception
- 为什么我的applet得到java.security.AccessControlException:访问被拒绝(java.net.SocketPermission …),我该如何避免它?