有效Java hashCode()实现中的位移位

有效Java hashCode()实现中的位移位,java,hashcode,Java,Hashcode,我想知道是否有人能详细解释一下 (int)(l^(l>>32)) 在以下hashcode实现中执行(由eclipse生成,但与有效Java相同): 谢谢 基本上,它将long的顶部32位与底部32位进行异或运算。以下是一个分解版本: // Unsigned shift by 32 bits, so top 32 bits of topBits will be 0, // bottom 32 bits of topBits will be the top 32 bits of l long top

我想知道是否有人能详细解释一下

(int)(l^(l>>32))

在以下hashcode实现中执行(由eclipse生成,但与有效Java相同):


谢谢

基本上,它将long的顶部32位与底部32位进行异或运算。以下是一个分解版本:

// Unsigned shift by 32 bits, so top 32 bits of topBits will be 0,
// bottom 32 bits of topBits will be the top 32 bits of l
long topBits = l >>> 32;

// XOR topBits with l; the top 32 bits will effectively be left
// alone, but that doesn't matter because of the next step. The
// bottom 32 bits will be the XOR of the top and bottom 32 bits of l
long xor = l ^ topBits;

// Convert the long to an int - this basically ditches the top 32 bits
int hash = (int) xor;

回答您的评论:您有一个长值,必须将其转换为int作为散列的一部分(结果必须只有32位)。你打算怎么做?你可以只取最下面的32位,但这意味着只有最上面的32位的变化会被忽略,这不会使它成为一个很好的散列。这样,一位输入的更改总是导致一位散列的更改。诚然,您仍然可以很容易地获得冲突-例如,更改位7和39,或者将任何其他对位32的位置分开-但这是必然的,因为您将从264个可能的值变为232。

它需要一个64位数字,将其拆分一半,然后将两半异或在一起(基本上)。

它需要一个(64位)
long
l
,异或将64位结果的上半部分和下半部分(各32位)转换为下32位,然后使用
(int)
强制转换只取下32位。

这样做的原因是什么?如果不这样做,你就不会得到同样有效的哈希代码吗?@Scobal:我已经扩展了我的答案来进一步解释。常数31(int prime)在这里有意义吗?或者我们可以取任何素数?@Diffy:这是一个棘手的问题,讨论了另一个与哈希相关的问题,我现在很难找到。我认为在这类散列中选择这类常数部分是科学部分是黑魔法。。。
// Unsigned shift by 32 bits, so top 32 bits of topBits will be 0,
// bottom 32 bits of topBits will be the top 32 bits of l
long topBits = l >>> 32;

// XOR topBits with l; the top 32 bits will effectively be left
// alone, but that doesn't matter because of the next step. The
// bottom 32 bits will be the XOR of the top and bottom 32 bits of l
long xor = l ^ topBits;

// Convert the long to an int - this basically ditches the top 32 bits
int hash = (int) xor;