Boolean.hashCode()

Posted

技术标签:

【中文标题】Boolean.hashCode()【英文标题】: 【发布时间】:2011-04-24 03:52:33 【问题描述】:

Boolean 类的hashCode() 方法是这样实现的:

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

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

【问题讨论】:

这两个数是足够大的素数。请阅读***上的article on Hash Table 了解更多信息。 【参考方案1】:

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

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

现在请注意

1000 % 82000 % 8 相同的存储桶 1000 % 102000 % 10 相同的存储桶 1000 % 202000 % 20 相同的存储桶 ....

换句话说,它会导致许多冲突

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

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

碰撞重要吗?布尔值只是有两个不同的值吗? 地图可以包含布尔值和其他对象。此外,正如 Drunix 所指出的,创建复合对象散列函数的常用方法是重用子组件散列代码实现,在这种情况下,最好返回大素数。

相关问题:

Why use a prime number in hashCode? What is a sensible prime for hashcode calculation? Why does Java's hashCode() in String use 31 as a multiplier?

【讨论】:

我想这些已经足够大了。要获得大于 1 的 gcd,您至少需要 2*1231 = 2462 存储桶。在这种情况下,碰撞会成为问题吗? 有趣的是,考虑到什么可以放入 int 中,它们并不是真的“相当大”。我想它们足够大,可以很好地与 JDK Hashtable 配合使用,但仍然足够小以最小化计算成本。 是的,我也觉得他们没有那么大。但是你认为更大的素数会带来更高的成本吗? @Thilo 您需要 1231*1237 = 1,522,747 个桶的倍数才能发生碰撞,这已经足够大了 我想说导致与桶计数的冲突并不是布尔值的真正问题,而是更多关于我们如何获得复合对象的哈希码的常见构造,即通过乘以组件的哈希码有一些常量并将它们相加。【参考方案2】:

除了上面所说的,它还可以是开发者的一个小彩蛋:

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

7 - 在欧洲传统中是一个幸运数字;

错误:1237 => 1 + 2 + 3 + 7 = 13

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

【讨论】:

以上是关于Boolean.hashCode()的主要内容,如果未能解决你的问题,请参考以下文章

重写hashcode和equals怎么重写

hashcode

hashCode

JAVA hashcode可以取八位吗

Java中的HashCode问题

hashCode方法的作用