- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这是我在 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 类(class)的详细信息,因为这无关紧要。 contains 方法在 equals 和 hash 没有的地方失败。
我并不是说 java 有问题或其他什么,我的代码中可能发生了一些有趣的事情。
请注意,我是一位经验丰富的 Java 程序员,我知道实现 equals 和 hashCode 的注意事项。因此,如果我的代码中缺少某些内容,这并不明显。
有没有人见过如此令人费解的事情?
编辑
我对我的代码做了一些研究,现在我认为问题出在 hibernate 中。我已经记录了 ActionPlan 对象的 hashCode,在创建之后,在代码的不同部分,直到调用失败的断言。 它不会改变。
我还检查了 assessment.getActionPlans() 返回的类,它是:
org.hibernate.collection.internal.PersistentSet
我很想相信这个 Set 的实现没有正确使用 equals 或 hashcode。
有人对此有见解吗?
最佳答案
有可能的解释
测试最后一种可能性的最简单方法是尝试
assertTrue(new HashSet(actionPlans).contains(actionPlan1));
我怀疑这会在您的案例中通过。 ;)
Date 有一个缺陷,它是可变的,而 hashCode 使用该可变字段,因此您可以通过改变它来破坏它所在的任何哈希集合。当您更改在 compareTo 中使用的字段时,会出现类似的问题。
Set<Date> dates = new HashSet<Date>();
SortedSet<Date> dates2 = new TreeSet<Date>();
Date d1 = new Date(1), d2 = new Date(2), d3 = new Date(3);
dates.add(d1);
dates.add(d2);
dates.add(d3);
dates2.add(d1);
dates2.add(d2);
dates2.add(d3);
d1.setTime(6);
d2.setTime(5);
d3.setTime(4);
System.out.print("The dates contains [");
for (Date date : dates) {
System.out.print("date " + date.getTime() + " ");
}
System.out.println("]");
System.out.print("The sorted dates2 contains [");
for (Date date : dates2) {
System.out.print("date " + date.getTime() + " ");
}
System.out.println("]");
for (int i = 1; i <= 6; i++)
System.out.println("date " + i + " found is " + dates.contains(new Date(i))
+ " and " + dates2.contains(new Date(i)));
打印
The dates contains [date 6 date 5 date 4 ]
The sorted dates2 contains [date 6 date 5 date 4 ]
date 1 found is false and false
date 2 found is false and false
date 3 found is false and false
date 4 found is false and false
date 5 found is false and true
date 6 found is false and false
注意:已排序的集合现在顺序错误。
关于Java Crazyness - 当 equals 通过时包含失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13603204/
这是我在 java (1.6) 中看到的最疯狂的事情: Set actionPlans = assessment.getActionPlans(); //getActionPlans() return
我是一名优秀的程序员,十分优秀!