我想知道是否有人可以详细解释什么
(int)(l ^ (l >>> 32));
在下面的hashcode实现中(由eclipse生成,但与Effective Java相同):
private int i;
private char c;
private boolean b;
private short s;
private long l;
private double d;
private float f;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + i;
result = prime * result + s;
result = prime * result + (b ? 1231 : 1237);
result = prime * result + c;
long t = Double.doubleToLongBits(d);
result = prime * result + (int) (t ^ (t >>> 32));
result = prime * result + Float.floatToIntBits(f);
result = prime * result + (int) (l ^ (l >>> 32));
return result;
}
谢谢!
答案 0 :(得分:31)
基本上,它使用最低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;
回答您的评论:您有一个long值,必须将其转换为int才能成为哈希的一部分(结果必须只有32位)。你打算怎么做?你可以只取底部的32位 - 但这意味着仅中的前32位的变化将被忽略,这不会使它成为一个非常好的散列。这样,输入总是的单个位的更改会导致散列的单个位的更改。不可否认,您仍然可以轻松地获得冲突 - 例如,更改两个位7和39,或者将任何其他位对32位置分开 - 但是这种情况肯定是这样的,因为您来自2 64 可能值为2 32 。
答案 1 :(得分:8)
它需要一个64位的数字,将它分成两半,然后将两半(基本上)合在一起。
答案 2 :(得分:4)
它需要一个(64位)long
l
,独占或者将上半部分和下半部分(每个32位)放入64位结果的底部32位,然后需要仅使用(int)
强制转换的底部32位。