类Boolean的hashCode()方法实现如下:
public int hashCode() {
return value ? 1231 : 1237;
}
为什么使用1231和1237?为什么不是别的?
1231和1237只是两个(足够大)的任意素数。任何其他两个大素数都可以。
为什么要素数?
假设我们选择了复合数字(非素数),比如1000和2000.当将布尔值插入哈希表时,true和false将进入桶1000 % N
resp 2000 % N
(其中N
是桶的数量)。
现在注意到了
1000 % 8
与2000 % 8
相同的桶1000 % 10
与2000 % 10
相同的桶1000 % 20
与2000 % 20
相同的桶换句话说,它会导致许多碰撞。
这是因为1000(23,53)的因式分解和2000(24,53)的因式分解有许多共同因素。因此选择素数,因为它们不太可能与桶大小有任何共同因素。
为什么大素数。不会2和3吗? 在计算复合对象的哈希码时,通常会为组件添加哈希码。如果在具有大量存储桶的哈希集中使用太小的值,则存在以不均匀的对象分布结束的风险。
碰撞是否重要?无论如何,布尔有两个不同的价值观? 地图可以包含布尔值以及其他对象。此外,正如Drunix所指出的,创建复合对象的哈希函数的常用方法是重用子组件哈希代码实现,在这种情况下返回大质数是很好的。
相关问题:
除了上面提到的所有内容之外,它还可以是来自开发人员的小型复活节彩蛋:
true:1231 => 1 + 2 + 3 + 1 = 7
7 - 是欧洲传统中的幸运数字;
false:1237 => 1 + 2 + 3 + 7 = 13
13(又名Devil's打) - 不幸的数字。