我不明白什么是0x7fffffff的意思。有没有其他方法来编写getHashValue方法?

时间:2018-03-31 22:21:55

标签: java

public int getHashValue(K key){
    return (key.hashCode() & 0x7fffffff) % size;
}

我不明白什么是0x7fffffff的意思。有没有其他方法来编写getHasValue方法?

3 个答案:

答案 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

在二进制表示中,第一位是信号。如果将其设置为零,则如果数字为负,则将获得正补充。如果是肯定的,也可以是相同的数字。