Boolean.hashCode()

use*_*011 117 java boolean hashcode

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

public int hashCode() {
    return value ? 1231 : 1237;
}
Run Code Online (Sandbox Code Playgroud)

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

aio*_*obe 136

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

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

现在注意到了

  • 1000 % 8 同样的桶 2000 % 8
  • 1000 % 10 同样的桶 2000 % 10
  • 1000 % 20 同样的桶 2000 % 20
  • ....

换句话说,它会导致许多碰撞.

这是因为1000(2 3 5 3 3)的因式分解和2000(2 4 5 3 3)的因子分解具有许多共同因素.因此选择素数,因为它们不太可能与桶大小有任何共同因素.

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

碰撞是否重要?无论如何,布尔有两个不同的价值观?
地图可以包含布尔值以及其他对象.此外,正如Drunix所指出的,创建复合对象的哈希函数的常用方法是重用子组件哈希代码实现,在这种情况下返回大质数是很好的.

相关问题:

  • @Thilo你需要多个1231*1237 = 1,522,747个桶才能碰撞,这足够大了 (3认同)
  • 有趣的是,考虑到什么可以适合int,它们并不是真的"相当大".我认为它们足够大,可以很好地与JDK Hashtable配合使用,但仍然足够小,可以最大限度地降低计算成本. (2认同)
  • 是的,它也让我感到震惊,他们不是那么大*.但是你认为较大的质数会有更高的成本吗? (2认同)
  • 我要说的是,与布尔值计数发生冲突并不是布尔值的真正问题,而是关于如何获取复合对象的hascode的更常见的构造,即通过将组件的哈希码与一些常量相乘并相加。 (2认同)

小智 6

除了上面所说的之外,它也可以是开发人员提供的一个小复活节彩蛋:

正确:1231 => 1 + 2 + 3 + 1 = 7

7——欧洲传统中的幸运数字;

假:1237 => 1 + 2 + 3 + 7 = 13

13(又名魔鬼打)——不吉利的数字。