使用哈希码确定对象等价

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,yplane领域,哈希码-因为他们应该-将是相等的.那么为什么不用来检查对象是否等价,而不是单独比较字段的值?

更明确地说,为什么不替换:

@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

Lou*_*man 6

想一想:Tile对于三个ints的每个组合,有2 ^ 32*2 ^ 32*2 ^ 32 = 2 ^ 96个不同的可能s.

只有2 ^ 32个可能的hashCodes.

因此,对于任何给定的Tile,将存在具有相同哈希码的2 ^ 64个不同的可能Tiles.

简而言之:哈希码不是唯一的. 许多对象碰巧具有相同的哈希码,即使它们不相等.

(一般来说,永远记住这return 0;是一个有效的实现hashCode().)