Java:只检查不可变对象的equals()中的hashCode

时间:2012-04-18 00:23:22

标签: java equals immutability guava hashcode

我有一个不可变对象,例如笛卡尔空间中的一个节点。该类是不可变的,因此我将hashCode缓存为非常快速的散列。

private final int hashCode;

private final double x, y, z;

public Node(final double x, final double y, final double z)
{
    this.x = x;
    this.y = y;
    this.z = z;
    this.hashCode = Objects.hashCode(this.x, this.y, this.z);
}

@Override
public boolean equals(final Object obj)
{
    if (this == obj) { return true; }
    if (obj == null) { return false; }
    if (!(obj instanceof Node)) { return false; }
    final Node other = (Node) obj;
    return Objects.equal(this.x, other.x) && Objects.equal(this.y, other.y) && Objects.equal(this.z, other.z);
}

@Override
public int hashCode()
{
    return this.hashCode;
}

由于hashCode是唯一的并且依赖于类的所有字段并且该类是不可变的,因此仅基于Node检查hashCode相等是否正确?

@Override
public boolean equals(final Object obj)
{
    if (this == obj) { return true; }
    if (obj == null) { return false; }
    if (!(obj instanceof Node)) { return false; }
    final Node other = (Node) obj;
    return this.hashCode == other.hashCode;
}

这传递了我所写的关于equals()hashCode()的属性及其相互作用的所有单元测试,但也许我有些遗漏?

注意:Objects.hashCode()Objects.equal()是对各自方法有帮助的番石榴类。

2 个答案:

答案 0 :(得分:17)

都能跟得上;这是行不通的。

您有2个 32 可能的哈希码和2个 192 可能的值。

答案 1 :(得分:2)

不,但是......

我想你可以检查一下哈希码,看看对象是否不等并在那里获得一些表现:

public boolean equals(final Object obj) {
   if (this == obj) { return true; }
   if (!(obj instanceof Node)) { return false; }
   final Node other = (Node) obj;

   if (this.hashCode != other.hashCode) {
      return false; // If hashcodes differ, we're sure the objects are not equal
   }
   // remainder of the actual equals implementation
}

当然,这只会在大多数比较产生错误的情况下提高性能。在对象相同的情况下,这将带来性能损失。在您的示例中(仅比较三个值),我不建议这样做。