Skip to content

质数

字数
766 字
阅读时间
4 分钟

在实现 hashCode 方法时,使用质数(Prime Numbers)作为哈希计算的一部分,是一种常见的优化策略。以下是使用质数的原因及其优势:


1. 质数的特性

质数是指只能被 1 和自身整除的自然数(如 2, 3, 5, 7, 11 等)。质数在哈希计算中有以下特性:

  • 分布均匀:质数在数学上分布较为均匀,能够减少哈希冲突的概率。
  • 减少冲突:质数作为哈希计算的乘数或模数时,能够更均匀地分散哈希值,避免多个对象映射到同一个哈希桶中。

2. 质数在哈希计算中的作用

在哈希函数中,质数通常用于以下场景:

  • 乘数:在计算哈希值时,将对象的属性值与一个质数相乘,可以增加哈希值的随机性和分散性。
  • 模数:在哈希表中,使用质数作为哈希表的大小(桶的数量),可以减少哈希冲突。

示例:使用质数作为乘数

java
public int hashCode() {
    int result = 17;  // 选择一个质数作为初始值
    result = 31 * result + field1.hashCode();  // 31 是另一个质数
    result = 31 * result + field2.hashCode();
    return result;
}
  • 17 和 31 是常用的质数,用于初始值和乘数。
  • 31 是一个小质数,具有以下优点:
    • 乘法计算可以通过位移和减法优化:31 * x = (x << 5) - x
    • 31 是一个奇质数,能够更好地分散哈希值。

3. 为什么质数不易冲突

  • 数学特性:质数与大多数数的乘积会生成一个独特的数,减少了哈希冲突的可能性。
  • 均匀分布:质数作为模数时,能够更均匀地将哈希值分布到哈希表的各个桶中,避免集中到某几个桶中。

示例:使用质数作为模数

java
int index = hashCode % tableSize;  // tableSize 是一个质数
  • 如果 tableSize 是质数,哈希值会均匀分布到各个桶中,减少冲突。
  • 如果 tableSize 不是质数(如 2 的幂),哈希值的低位可能重复,导致冲突增加。

4. 实际应用

在 Java 中,许多类的 hashCode 实现都使用了质数。例如:

  • String 类的 hashCode 实现

    java
    public int hashCode() {
        int h = 0;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + value[i];
        }
        return h;
    }
    • 31 是一个质数,用于计算字符串的哈希值。
  • HashMap 的哈希表大小

    • HashMap 的初始容量和扩容后的容量通常是质数或接近质数的数,以减少哈希冲突。

贡献者

文件历史