public int getHashValue(K key){
return (key.hashCode() & 0x7fffffff) % size;
}
我不明白什么是0x7fffffff的意思。有没有其他方法来编写getHasValue方法?
答案 0 :(得分:8)
常量0x7FFFFFFF
是一个十六进制的32位整数,除了最高位之外都有。
尽管有这个名字,但这个方法并没有得到hashCode,而是在寻找密钥应该出现在哈希集或映射中的哪个存储桶。
在负值上使用%
时,您会得到一个负值。没有负面的桶,所以为了避免这种情况,你可以删除符号位(最高位),这样做的一种方法是使用掩码,例如x & 0x7FFFFFFF
保留除最顶层之外的所有位。另一种方法是移动输出x >>> 1
,但速度较慢。
稍微好一点的方法是使用“取模数并应用Math.abs”。这使用了hashCode的所有可能更好的位。
e.g。
public int getBucket(K key) {
return Math.abs(key.hashCode() % size);
}
即使这样也不理想,因为一些hashCode()的分布很差,导致更高的冲突率。你可能想在模数等之前激动哈希码。
public int getBucket(K key) {
return Math.abs(hash(key) % size);
}
java 8中的HashMap使用此
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
该功能很简单,因为它可以有效地处理冲突。在Java 7中,它使用了这个函数。
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
答案 1 :(得分:1)
这是Max的十六进制表示。整数
您可以查看 here
答案 2 :(得分:0)
0x7fffffff
只需删除获得数字补码的信号。
使用Java REPL,您可以看到操作的结果
> -7 & 0x7fffffff
java.lang.Integer res1 = 2147483641
> 2147483641 & 0x7fffffff
java.lang.Integer res2 = 2147483641
> 2147483641 + 6
java.lang.Integer res3 = 2147483647
> 7 + 2147483641
java.lang.Integer res4 = -2147483648
在二进制表示中,第一位是信号。如果将其设置为零,则如果数字为负,则将获得正补充。如果是肯定的,也可以是相同的数字。