我在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<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添加到调用equals?
答案 0 :(得分:25)
如果哈希码不同,则无需致电equals()
,因为保证会返回false
。
以下是equals()
和hashCode()
上的一般contract:
如果两个对象根据
equals(Object)
方法相等,则在两个对象中的每一个上调用hashCode
方法必须产生相同的整数结果。
现在你的班级违反了合同。你需要解决这个问题。
答案 1 :(得分:5)
如果您希望始终调用equals()
,请始终在0
中返回hashCode()
。这样,所有项目都具有相同的哈希码,并且仅与equals()
进行比较。
public int hashCode() {
return 0;
}
答案 2 :(得分:1)
听起来HashSet不适合你。 听起来你想要一种比较两个位置的自定义方式。而不是说“两个位置完全相同?”。 相反,您应该使用比较器来查看TreeSet。这样,您可以编写“IsWithinRangeComparator”并在那里进行范围检查。
答案 3 :(得分:-1)
如上所述,当对象相等时,它们的哈希码也应该相同。 您可以对哈希码计算进行简单的修复,如下所示。
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;
}