Boolean.hashCode()


Answers:


139

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

为什么要灌注?
假设一秒钟,我们挑选合数(非素数),说1000年和2000年当插入到布尔哈希表,会进入斗1000 % NRESP 2000 % N(这里N是桶的数量)。

现在注意

  • 1000 % 8 与同一桶 2000 % 8
  • 1000 % 10 与同一桶 2000 % 10
  • 1000 % 20 与同一桶 2000 % 20
  • ....

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

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

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

碰撞重要吗?布尔值到底有两个不同的值吗?
映射可以包含布尔值以及其他对象。同样,正如Drunix所指出的,创建复合对象的哈希函数的一种常见方法是重用子组件哈希代码的实现,在这种情况下,返回大素数是很好的。

相关问题:


1
我认为这些足够大。要使gcd大于1,您至少需要2*1231 = 2462存储桶。在这种情况下碰撞会成为问题吗?
aioobe

2
有趣的是,考虑到可以容纳一个int的对象,它们并不是真正的“相当大”。我想它们足够大,可以与JDK Hashtable一起很好地工作,但又足够小,可以最大程度地减少计算成本。
Thilo

2
是的,我也感到震惊,因为它们不那么大。但是您相信更大的素数会有更高的成本吗?
aioobe

3
@Thilo,您需要1231 * 1237 = 1,522,747桶的倍数才能发生碰撞,这足够大
棘轮异常

2
我要说的是,与布尔值计数发生冲突并不是布尔值的真正问题,而是有关如何获取复合对象的hascode的更常见的构造,即通过将组件的哈希码与一些常量相乘并相加。
Drunix 2014年

2

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

true:1231 => 1 + 2 + 3 + 1 = 7

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

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

13(又名Devil的打)-不幸的数字。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.