hashCode()方法中使用系数31的原因
来源:互联网 发布:tonymoly口红比mac 编辑:程序博客网 时间:2024/05/17 01:26
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
该函数是我看的函数接口源码,为什么要使用31这个数呢?
其实上面的实现也可以总结成数数里面下面这样的公式:
s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1]
大家都知道,计算机的乘法涉及到移位计算。当一个数乘以2时,就直接拿该数左移一位即可!选择31原因是因为31是一个素数!
所谓素数:
质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。
在存储数据计算hash地址的时候,我们希望尽量减少有同样的hash地址,所谓“冲突”。如果使用相同hash地址的数据过多,那么这些数据所组成的hash链就更长,从而降低了查询效率!所以在选择系数的时候要选择尽量长(31 = 11111[2])的系数并且让乘法尽量不要溢出(如果选择大于11111的数,很容易溢出)的系数,因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。
原因如下:
A.31是一个素数,素数作用就是如果我用一个数字来乘以这个素数,那么最终的出来的结果只能被素数本身和被乘数还有1来整除!。(减少冲突)
B.31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化.(提高算法效率)
C.选择系数的时候要选择尽量大的系数。因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。(减少冲突)
D.并且31只占用5bits,相乘造成数据溢出的概率较小。
PS:这几点原因为从别的博文中复制,这里只是做个记录,正确与否还未考证.
阅读全文
0 0
- hashCode()方法中使用系数31的原因
- 关于hashcode 里面 使用31 系数的问题
- 关于hashcode 里面 使用31 系数的问题
- 【转载】关于hashcode里面使用31系数的问题
- 关于hashCode里面使用31系数的问题
- 关于hashcode 里面 使用31 系数的问题
- 关于hashcode 里面 使用31 系数的问题
- 关于hashcode 里面 使用31 系数的问题
- JAVA中重写自己的hashCode()方法原因
- hashCode方法的使用
- hashCode方法的使用
- 关于HashCode与其系数31
- [JAVA]Java中hashCode和equals方法的使用
- JAVA中HashCode和equals方法的使用
- Java中hashCode()和equal()方法的使用
- java中equals与hashcode的方法使用
- 重写equals方法一般需要重写hashCode方法的原因
- 重写equals()方法就必须重写hashCode()方法的原因
- soapui中文操作手册(四)----MOCK服务
- Dll入口函数参数详解
- 数据库_MySQL
- 学习一个random_shuffle()
- 引脚配置输入输出
- hashCode()方法中使用系数31的原因
- Swift内存模型的那点事儿
- vue中 具名slot的用法
- Java中的关键字与修饰符
- oracle查看表空间使用情况
- OC语言学习10-NSFileManager类的应用
- hdu1394(求逆序数)
- 局域网访问MySql
- (卡特兰数)Train Problem II --HDOJ