当前位置: 首页 > 知识库问答 >
问题:

为什么TreeSet抛出一个ClassCastExcure?

田德馨
2023-03-14

我试图将两个“Employee”对象添加到树集中:

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));

或者如果我使用哈希集:

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

那么它就是成功的。为什么会发生异常,如何修复它?

共有3个答案

寿阳华
2023-03-14

从TreeSet#添加(E)JavaDoc:

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

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

如果选中TreeMapcode,您将看到,如果在Map对象中找不到比较器,它将尝试将键(您的员工对象)直接投射到比较器

...
Comparable<? super K> k = (Comparable<? super K>) key;
...
海鸣
2023-03-14

TreeSet如果没有设置自定义比较器,则需要元素来实现可比接口。

只能将一个元素添加到TreeSet中,该元素不实现compariable,因为它不需要与其他元素进行比较。

看看树形图。输入(K键,V值)源代码,你就会清楚地看到你所有问题背后的原因(TreeSet基于TreeMap,因此是源代码参考)。

晋坚
2023-03-14

要么雇员必须实现可比,要么在创建TreeSet时需要提供一个比较器。

这在SortedSet的留档中详细说明:

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

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

 类似资料:
  • 问题内容: 我试图将两个’Employee’对象添加到TreeSet中: 但是它抛出一个ClassCastException: 但是,如果我仅将一个对象添加到TreeSet中: 或者,如果我改用HashSet: 那就成功了。为什么会发生异常,我该如何解决? 问题答案: 要么必须实现,或者你需要提供一个比较创建时。 在文档中对此进行了详细说明: 插入排序集中的所有元素都必须实现接口(或被指定的比较器

  • 这是Google Guice调用代码: 这是个例外: 我的问题是消息没有告诉我缺少哪一个特定的方法。有没有好的方法来调试这个?这可能是一个Maven传递依赖问题吗?

  • 问题内容: 我在编写Traveling Salesman程序时遇到了这个问题。对于内部循环,我尝试了 但是在该列表中添加另一个点时会导致被抛出。 但是,当我将循环更改为 循环运行良好,没有引发异常。 这两个都是for循环,那么为什么一个抛出异常却另一个没有抛出异常呢? 问题答案: 正如其他人解释的那样,迭代器检测到对基础集合的修改,这是一件好事,因为它可能会导致意外的行为。 想象一下下面的无迭代器

  • 问题内容: final Multimap terms = getTerms(bq); for (Term t : terms.keySet()) { Collection C = new HashSet(terms.get(t)); if (!C.isEmpty()) { for (Iterator it = C.iterator(); it.hasNext();) { BooleanClause

  • 问题内容: 将字符串解析为字节时出现异常 问题答案: 这是因为默认的parse方法要求使用十进制格式的数字来解析十六进制数字,请使用以下parse: 其中16是解析的基础。 至于您的评论,您是对的。字节的最大值为0x7F。因此,您可以将其解析为并执行二进制与操作以获得LSB,即您的字节:

  • 问题内容: 我有这种方法: 映射: Person.hbm.xml Cars.hbm.xml 此方法适用于单个线程,并且在多个线程上,给我一个错误: AOP交易: 注意:当我在更新后添加Thread.sleep(5000)时,就可以了。 但是这种解决方案并不干净。 问题答案: 我有汽车->(1-n)个地方。而且我在表位置(id_car)有一个外键。此外键没有索引。当我向该外键添加索引时,我的问题已解