为什么 String hashCode 方法选择数字31作为乘子

Posted blogfortang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么 String hashCode 方法选择数字31作为乘子相关的知识,希望对你有一定的参考价值。

参考文章:

hashCode 为什么乘以 31?深入理解 hashCode 和 hash 算法

https://www.jianshu.com/p/76c5215eda5c

为什么 String hashCode 方法选择数字31作为乘子

https://segmentfault.com/a/1190000010799123

为什么在定义hashcode时要使用31这个数呢?

https://blog.csdn.net/mingli198611/article/details/10062791

 总结:

定义hashcode时要使用31作为乘子主要有以下几个原因:

A、31 有个很好的性能,即用移位和减法来代替乘法,可以得到更好的性能: 31 * i == (i << 5)- i, 现代的 VM 可以自动完成这种优化。

B、31是一个奇素数,选择素数(质数)的好处就是如果我用一个数字来乘以这个素数,那么最终出来的结果也只能被素数本身和被乘数(以及被乘数的整除因子)还有1来整除!这样,以31作为乘子参与乘法计算得出的hashcode值,在后面进行取模(实际上是与运算时),得到相同index的概率会降低,即降低了哈希冲突的概率。

C、31作为一个既不太大又不太小的乘子,计算出来的hashcode值范围处于一个“适中”的区间,能够很好的降低哈希冲突,进行数据查找时可以提高效率。一方面,乘子太小容易导致计算出来的hashcode值范围处于一个“较小”的区间,在后面进行取模(实际上是与运算时),得到相同index的概率会升高,即哈希冲突的概率会提高;另一方面,乘子太大可能会导致相乘时造成数据溢出的概率增大。

D、31只占用5bits(11111B),相乘造成数据溢出的概率较小。

以上是关于为什么 String hashCode 方法选择数字31作为乘子的主要内容,如果未能解决你的问题,请参考以下文章

String hashCode 方法为什么选择数字31作为乘子

JDK1.8源码学习-String-hashCode方法为什么选择数字31作为乘子

BTA 常问的 Java基础40道常见面试题及详细答案(山东数漫江湖))

为什么重写equals时必须重写hashCode方法?(转发+整理)

为什么重写equals方法必须重写hashCode?

java 集合中重写hashCode方法和重写equals方法啥关系?