【发布时间】:2013-01-08 10:03:23
【问题描述】:
我在 HashSet 比较中做了这个测试,equals 没有被调用
我想在 farAway=false 时考虑 equals (检查两点距离的函数)
完整的可编译代码,您可以对其进行测试,并说明为什么在此示例中未调用 equals。
public class TestClass{
static class Posicion
{
private int x;
private int y;
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Posicion other = (Posicion) obj;
if ( farAway(this.x, other.x, this.y, other.y,5)){
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y;
return hash;
}
Posicion(int x0, int y0) {
x=x0;
y=y0;
}
private boolean farAway(int x, int x0, int y, int y0, int i) {
return false;
}
}
public static void main(String[] args) {
HashSet<Posicion> test=new HashSet<>();
System.out.println("result:"+test.add(new Posicion(1,1)));
System.out.println("result:"+test.add(new Posicion(1,2)));
}
}
编辑
-有没有办法强制HashSet add to call equals?
【问题讨论】:
-
farAway在equals中的调用是什么?你的班级违反了hashCode和equals之间的合同! -
@AlonsoDominguez 你有一个完整的测试,farAway 只是返回 false,以确保对象被视为相等,但永远不会调用 equals。
-
您必须遵守
hashCode和equals之间的合同。这意味着当您的equals方法返回 true 时,您的hashCode必须返回相同的整数值。而这并没有发生在您的代码中。 -
@AlonsoDominguez 我明白,我试图避免 hashCode,并且只使用equals,我现在看到这是不可能的,感谢contract break,那么现在我知道equals 不何时被调用,我仍然不知道equals 何时真正被调用。
-
@HernánEche:您似乎想要做的事情可能非常棘手 - 您不仅必须遵守
hashCode()的合同,还要遵守equals()的合同。equals()必须是可传递的。因此,如果您为 A 和 B 返回true因为它们彼此接近,而 B 和 C 因为它们彼此接近而返回,那么在检查 A 和 C 之间的相等性时,如果它们碰巧不接近,您将遇到问题.我认为你需要设计一个标准 HashSet 以外的容器/数据结构来做你想做的事情(如果你想做的事情首先是一个好主意)。
标签: java comparison equals hashset