pho*_*360 4 java contains equals set
这是我在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));
Run Code Online (Sandbox Code Playgroud)
前两个断言通过,但最后一个失败.
我没有向您提供有关ActionPlan和评估课程的详细信息,因为它无关紧要.contains方法失败,而equals和hash则没有.
我不是说java已经破坏或者其他什么,我的代码中可能会发生一些有趣的事情.
请注意,我是一名经验丰富的java程序员,我知道dos并不知道实现equals和hashCode.因此,如果我的代码中缺少某些东西,那就不是显而易见的了.
有没有人见过令人费解的事情?
编辑
我在我的代码中做了一些研究,现在我认为问题在于休眠.我在创建之后,在代码的不同部分记录了ActionPlan对象的hashCode,直到调用失败的断言.它没有改变.
我还检查了assessment.getActionPlans()返回的类,它是:
org.hibernate.collection.internal.PersistentSet
Run Code Online (Sandbox Code Playgroud)
我很想相信Set的这个实现不能正确使用equals或hashcode.
有没有人对此有所了解?
Pet*_*rey 12
有可能解释
测试最后一种可能性的最简单方法是尝试
assertTrue(new HashSet(actionPlans).contains(actionPlan1));
Run Code Online (Sandbox Code Playgroud)
我怀疑这会在你的情况下通过.;)
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)));
Run Code Online (Sandbox Code Playgroud)
版画
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
Run Code Online (Sandbox Code Playgroud)
注意:已排序的集合现在顺序错误.
如果您重载equals 但不覆盖 , equals(Object)就会发生这种情况。
例如,您可能有:
public boolean equals(ActionPlan plan) {
...
}
Run Code Online (Sandbox Code Playgroud)
这将被调用:
assertTrue(actionPlan1.equals(actionPlan));
Run Code Online (Sandbox Code Playgroud)
...但不会被调用contains。你需要:
@Override public boolean equals(Object object) {
...
}
Run Code Online (Sandbox Code Playgroud)
当然,也有可能事实并非如此。如果没有看到您的代码,我们无法确定。
我不会向您提供有关行动计划和评估课程的详细信息,因为这并不重要。
这个答案与该假设相矛盾……彼得的答案也是如此,其中包含替代故障模式。这就是为什么给出一个简短但完整的例子总是很重要的。
| 归档时间: |
|
| 查看次数: |
1933 次 |
| 最近记录: |