HashSet’add’方法调用何时等于?
我在HashSet比较中做了这个测试,并且没有调用 equals
当farAway = false时,我想考虑等于(检查两个点距离的函数)
完全可编译的代码,你可以测试它,并告诉为什么在这个例子中没有调用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 test=new HashSet(); System.out.println("result:"+test.add(new Posicion(1,1))); System.out.println("result:"+test.add(new Posicion(1,2))); } }
编辑
– 有没有办法强制HashSet添加到调用equals?
如果哈希码不同,则不需要调用equals()
因为它保证返回false
。
这是来自equals()
和hashCode()
的一般合约 :
如果两个对象根据
equals(Object)
方法equals(Object)
,则对两个对象中的每一个调用hashCode
方法必须生成相同的整数结果。
现在你的class级打破了合同。 你需要解决这个问题。
如果你想要总是调用equals()
,那么总是在hashCode()
返回0
。 这样,所有项都具有相同的哈希码,并且仅与equals()
进行比较。
public int hashCode() { return 0; }
听起来HashSet不适合你。 听起来你想要一种比较两个位置的自定义方式。 而不是说“两个位置完全相同?”。 相反,您应该使用比较器来查看TreeSet。 这样,您可以编写“IsWithinRangeComparator”并在那里进行范围检查。
如上所述,当对象相等时,它们的哈希码也应该相同。 您可以对下面的哈希码计算进行简单的修复。
public int hashCode() { int hash = 7; hash = 59 * hash + this.x; hash = 59 * hash + this.y; boolean faraway=farAway(this.x, other.x, this.y, other.y,5); hash=59*hash+(faraway?1:0); //include faraway also as part of hashcode computation return hash;
}