重写 hashCode() - 这足够好吗?
对于字段仅为原始字段的类,例如:
class Foo
{
int a;
String b;
boolean c;
long d;
boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof Foo)) return false;
Foo other = (Foo) o;
return a == other.a && b.equals(other.b) && c == other.c && d = other.d;
}
}
这是编写 hashCode()
的合理“足够好”的方式吗?
boolean hashCode()
{
return (b + a + c + d).hashCode();
}
也就是说,我构造了一个 String
与 equals()
使用的相同字段分开,然后只需使用 String#hashCode()
。
编辑:我已更新我的问题以包含一个长
字段。 long
应该如何在 hashCode()
中处理?就让它溢出int
?
For a class whose fields are solely primitive, ex.:
class Foo
{
int a;
String b;
boolean c;
long d;
boolean equals(Object o)
{
if (this == o) return true;
if (!(o instanceof Foo)) return false;
Foo other = (Foo) o;
return a == other.a && b.equals(other.b) && c == other.c && d = other.d;
}
}
Is this a reasonably "good enough" way to write hashCode()
?
boolean hashCode()
{
return (b + a + c + d).hashCode();
}
That is, I construct a String
out of the same fields that equals()
uses, and then just use String#hashCode()
.
Edit: I've updated my question to include a long
field. How should a long
be handled in hashCode()
? Just let it overflow int
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的哈希码确实满足以下属性:如果两个对象相等,则它们的哈希码必须相等。所以,从这个角度来说,它已经“足够好”了。然而,在哈希码中创建冲突相当简单,这会降低基于哈希的数据结构的性能。
不过,我的实现方式略有不同:
您应该查看
Object
的hashCode()
方法 的文档。它列出了哈希码必须满足的条件。Your hash code does satisfy the property that if two objects are equal, then their hash codes need to be equal. So, in that way it is 'good enough'. However, it is fairly simple to create collisions in the hash codes which will degrade the performance of hash based data structures.
I would implement it slightly differently though:
You should check out the documentation for the
hashCode()
method ofObject
. It lays out the things that the hash code must satisfy.这完全取决于您的数据是什么样子。在大多数情况下,这将是一个很好的方法。如果您经常使用
b
以数字结尾,那么您会得到一些不相等对象的重复代码,如 JacobM 的答案所示。如果您提前知道 b 末尾几乎不会有数字值,那么这是一个合理的哈希算法。It totally depends on what your data will look like. Under most circumstances, this would be a good approach. If you'll often have
b
end with a number, then you'll get some duplicate codes for unequal objects, as JacobM's answer shows. If you know ahead of time that b will pretty much never have a number value at the end, then this is a reasonable hashing algorithm.