【发布时间】:2012-11-16 04:39:08
【问题描述】:
这是我在java(1.6)中看到的最疯狂的事情:
Set<ActionPlan> actionPlans = assessment.getActionPlans();
//getActionPlans() returns a java.util.HashSet<ActionPlan>
ActionPlan actionPlan = actionPlans.iterator().next();
assertTrue(actionPlan1.equals(actionPlan));
assertEquals(actionPlan1.hashCode(), actionPlan.hashCode());
assertTrue(actionPlans.contains(actionPlan1));
前两个断言通过,但最后一个失败。
我不会向您提供有关 ActionPlan 和 Assessment 课程的详细信息,因为这无关紧要。 contains 方法在 equals 和 hash 没有的地方失败。
我并不是说 java 坏了或其他什么,我的代码中可能发生了一些有趣的事情。
请注意,我是一位经验丰富的 java 程序员,并且我知道 dos 并且不知道实现 equals 和 hashCode。因此,如果我的代码中缺少某些内容,那并不是很明显。
有没有人见过令人费解的事情?
编辑
我对我的代码进行了一些研究,现在我认为问题出在休眠状态。我已经记录了 ActionPlan 对象的 hashCode,在创建之后以及代码的不同部分,直到调用失败的断言。 不会改变。
我还检查了由assessment.getActionPlans() 返回的类,它是:
org.hibernate.collection.internal.PersistentSet
我很想相信 Set 的这个实现没有正确使用 equals 或 hashcode。
有人对此有见解吗?
【问题讨论】:
-
另请注意,Assessment 和 ActionPLan 对象是使用 TRANSACTION 类型的持久性上下文检索的 JPA(使用休眠实现)实体。
-
您能显示
ActionPlan的等号和哈希码吗?这应该很重要。 -
我认为发布您的代码 - 特别是 equals/hashCode 是 key 到此
-
您已经承认“[您的]代码中可能发生了一些有趣的事情”——但您认为该代码无关紧要?奇数。
-
根据 Set 对象的类,我们可能还需要 compareTo 或 Comparator 实现,以及 equals 和 hashCode 声明。例如,在目前有限的信息中,我们可以处理一个 TreeSet 和一个 compareTo 与 equals 不一致的类。