问题

类Boolean的hashCode()方法实现如下:

public int hashCode() {
    return value ? 1231 : 1237;
}

为什么使用1231和1237?为什么不是别的?


#1 热门回答(128 赞)

1231和1237只是两个(足够大)任意素数.任何其他两个大素数都可以。

为什么要素数?
假设我们选择了复合数字(非素数),比如1000和2000.当将布尔值插入哈希表时,trueandfalse将进入bucket1000 % Nresp2000 % N(其中,N是桶的数量)。

现在注意到了

  • 1000%8相同桶,2000%8
  • 1000%10相同桶,2000%10
  • 1000%20相同桶,2000%20
  • ....

换句话说,它会导致很多碰撞。

这是因为1000(23,53)的因子分解和2000(24,53)的因式分解有许多共同因素。因此选择素数,因为它们不太可能与桶大小有任何共同因素。

Whylargeprimes。不会2和3吗?
在计算复合对象的哈希码时,通常会为组件添加哈希码。如果在具有大量存储桶的哈希集中使用太小的值,则存在以不均匀的对象分布结束的风险。

碰撞是否重要?无论如何,布尔有两个不同的价值观?
Map 可以包含与其他对象一起的布尔值。另外,正如Drunix所指出的,创建复合对象的哈希函数的常用方法是重用子组件哈希代码实现,在这种情况下返回大质数是很好的。
相关问题: - 为什么在hashCode中使用素数?

  • 什么是哈希码计算的合理素数?
  • 为什么String中的Java hashCode()使用31作为乘数?

原文链接