【发布时间】:2011-05-01 23:57:09
【问题描述】:
我有一系列具有long 字段的对象,该字段的值唯一地标识了整个系统中的特定对象,很像 GUID。我已覆盖 Object.equals() 以使用此 id 进行比较,因为我希望它与对象的副本一起使用。现在我也想覆盖Object.hashCode(),这基本上意味着将我的long 映射到一些int 返回值。
如果我正确理解hashCode 的用途,它主要用于哈希表,因此需要均匀分布。这意味着,只需返回 id % 2^32 就足够了。仅此而已,还是我应该注意其他事情?
【问题讨论】:
-
顺便说一句,即使您只想保留低 32 位,也不需要模运算。投射到
int就足够了:int hashCode = (int) id。 -
@Grodriguez 抱歉,但这个答案很糟糕!它将导致许多对象具有相同的哈希码,从而产生各种哈希冲突。你总是想要均匀分布的哈希码。此外,公认的答案也不是最佳解决方案,因为 java 8 引入了更好的解决方案。请参考“Nathan”给出的答案,因为
Long.hashcode(long)不会在堆栈上创建新对象 -
@Neuron 任何将 64 位值映射到 32 位值的哈希函数都会“导致许多对象具有相同的哈希码”。根本没有办法避免这种情况。此外,不能保证
(this.longValue()^(this.longValue()>>>32))产生的散列码比仅保留值的低 32 位更均匀。 -
@Grodriguez 是的,再次抱歉。你说的对。我没有意识到将 long 转换为 int 会包裹 int 而不会分别停留在
Integer.MAX_VALUE或MIN_VALUE上,我是否会期望演员实际上正在做..