Mar*_*ius 2 java hash equivalence
假设我有一个代表游戏牌的简单类,称为Tile
:
public class Tile {
public final int x;
public final int y;
public final int plane;
public Tile(int x, int y, int plane) {
this.x = x;
this.y = y;
this.plane = plane;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj instanceof Tile) {
Tile other = (Tile) obj;
return other.x == x && other.y == y && other.plane == plane;
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(x, y, plane);
}
}
Run Code Online (Sandbox Code Playgroud)
作为一个负责任的公民,我实现了这个hashCode
方法,以确保等效对象的哈希码是相等的,每个合约equals
.然后我就在想,对于任何两个Tile
具有相同值的对象x
,y
和plane
领域,哈希码-因为他们应该-将是相等的.那么为什么不用它来检查对象是否等价,而不是单独比较字段的值?
更明确地说,为什么不替换:
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
} else if (obj instanceof Tile) {
Tile other = (Tile) obj;
return other.x == x && other.y == y && other.plane == plane;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
简单地说:
@Override
public boolean equals(Object obj) {
return obj == this || obj != null && obj.hashCode() == hashCode();
}
Run Code Online (Sandbox Code Playgroud)
我的一部分认为这是不好的做法.这几乎就像循环推理一样.但是,我想不出一个有效的,实际的理由,为什么这将是一个不好的做法.
简而言之:使用结果hashCode
来确定结果是否合适equals
?
想一想:Tile
对于三个int
s的每个组合,有2 ^ 32*2 ^ 32*2 ^ 32 = 2 ^ 96个不同的可能s.
只有2 ^ 32个可能的hashCode
s.
因此,对于任何给定的Tile
,将存在具有相同哈希码的2 ^ 64个不同的可能Tile
s.
简而言之:哈希码不是唯一的. 许多对象碰巧具有相同的哈希码,即使它们不相等.
(一般来说,永远记住这return 0;
是一个有效的实现hashCode()
.)
归档时间: |
|
查看次数: |
126 次 |
最近记录: |