hashcode中选择31因子的原因

源自<<effective java 2nd>> Item9

 

The value 31 was chosen because it is
an odd prime. If it were even and the multiplication overflowed, information
would be lost, as multiplication by 2 is equivalent to shifting. The advantage of
using a prime is less clear, but it is traditional. A nice property of 31 is that the
multiplication can be replaced by a shift and a subtraction for better performance:
31 * i == (i < < 5) - i. Modern VMs do this sort of optimization automatically.

主要是关于 result = 31 * result + c 这个式子中为什么用31,他说31是奇数,不是偶数,如果是偶数且乘法造成溢出的话,信息就会丢失,因为乘以2就相当于移位,那我就有个疑惑了,乘31就 不会造成信息丢失了?乘2是移位,乘31的过程其实也是包含移位的

 

MT502回答说:乘31和2都会溢出造成信息丢失,但是乘2更容易导致低位都变成0从而导致hashcode一样的概率变大

 

我认为乘31也没有理由不造成溢出,看来原文描述确实有些语病。

 

选择31这个质数,至少是有意让hash值最大程度散布,降低碰撞可能~

 

For what it's worth, Effective Java 2nd Edition hand-waives around the mathematics issue and just say that the reason to choose 31 is:

  * Because it's an odd prime, and it's "traditional" to use primes
  * It's also one less than a power of two, which permits for bitwise optimization

Here's the full quote, from Item 9: Always override hashCode when you override equals:

  The value 31 was chosen because it's an odd prime. If it were even and multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional.

  A nice property of 31 is that the multiplication can be replaced by a shift (§15.19) and subtraction for better performance:

  31 * i == (i << 5) - i

  Modern VMs do this sort of optimization automatically.

  While the recipe in this item yields reasonably good hash functions, it does not yield state-of-the-art hash functions, nor do Java platform libraries provide such hash functions as of release 1.6. Writing such hash functions is a research topic, best left to mathematicians and theoretical computer scientists.

  Perhaps a later release of the platform will provide state-of-the-art hash functions for its classes and utility methods to allow average programmers to construct such hash functions. In the meantime, the techniques described in this item should be adequate for most applications.

Rather simplistically, it can be said that using a multiplier with numerous divisors will result in more hash collisions. Since for effective hashing we want to minimize the number of collisions, we try to use a multiplier that has fewer divisors. A prime number by definition has exactly two distinct, positive divisors.

 

http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode

 

其它相关信息stackoverflow上也有不少,如:

http://stackoverflow.com/questions/299304/why-does-javas-hashcode-in-string-use-31-as-a-multiplier

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值