A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

hashCode()方法的重写:
        @Override
        public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + age;
                result = prime * result + ((name == null) ? 0 : name.hashCode());
                return result;
        }
有点不太懂,为什么hashCode()方法里面的常量值是31,其他的数不可以吗?



15 个回复

倒序浏览
CC12300320 来自手机 初级黑马 2016-9-7 14:05:34
沙发
计算机的乘法涉及到移位计算。当一个数乘以2时,就直接拿该数左移一位即可!选择31原因是因为31是一个素数!

所谓素数:

质数又称素数。指在一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数。

在存储数据计算hash地址的时候,我们希望尽量减少有同样的hash地址,所谓“冲突”。如果使用相同hash地址的数据过多,那么这些数据所组成的hash链就更长,从而降低了查询效率!所以在选择系数的时候要选择尽量长(31 = 11111[2])的系数并且让乘法尽量不要溢出(如果选择大于11111的数,很容易溢出)的系数,因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。

31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化,使用31的原因可能是为了更好的分配hash地址,并且31只占用5bits!

在java乘法中如果数字相乘过大会导致溢出的问题,从而导致数据的丢失.

而31则是素数(质数)而且不是很长的数字,最终它被选择为相乘的系数的原因不过与此!
回复 使用道具 举报
楼上正解
回复 使用道具 举报
* 1,31是一个质数,质数是能被1和自己本身整除的数
* 2,31这个数既不大也不小
* 3,31这个数好算,2的五次方-1,2向左移动5位
回复 使用道具 举报
厉害厉害!!
回复 使用道具 举报
jinxiliuhuo 发表于 2016-9-7 18:49
* 1,31是一个质数,质数是能被1和自己本身整除的数
* 2,31这个数既不大也不小
* 3,31这个数好算,2的五次方-1 ...

我感觉回答的有些道理
回复 使用道具 举报
细听风语为梧桐 发表于 2016-9-7 21:47
我感觉回答的有些道理

额,上课时是这么讲的,通俗一点
回复 使用道具 举报
高手多..............
回复 使用道具 举报
通过统一定义 equals() 和 hashCode(), 可以提升类作为基于散列的集合中的关键字的使用性。究其根本,是Java规范在作祟,每个Java对象都有 hashCode() 和 equals() 方法。许多类根本就忽略了(Override)这些方法的缺省实施
回复 使用道具 举报
jinxiliuhuo 发表于 2016-9-7 18:49
* 1,31是一个质数,质数是能被1和自己本身整除的数
* 2,31这个数既不大也不小
* 3,31这个数好算,2的五次方-1 ...

移4位吧
回复 使用道具 举报
1.31是一个质数,只能被1和它本身整除;    2.31这个数即不大也不小,计算hashCode的值不容易超出int的取值范围;    3.31这个数容易计算,只要是2向左移动5减1即可。
回复 使用道具 举报

诶,还真没注意,底数为2的确是4位。。。
回复 使用道具 举报
刘永川 来自手机 中级黑马 2016-9-8 00:21:08
13#
刚学习过去,真没注意到这个东西,楼主真是细心,学校里,谢谢啊
回复 使用道具 举报
讲得太好了 ,顶顶顶!!!
回复 使用道具 举报
jinxiliuhuo 发表于 2016-9-8 00:18
诶,还真没注意,底数为2的确是4位。。。

哈哈哈
回复 使用道具 举报
楼上的几位答案太标准了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马