重写hashcode的原因 以及为啥用31的个人理解
来源:互联网 发布:java构造器使用实例 编辑:程序博客网 时间:2024/05/29 19:04
首先声明自己大部分的理解的出处:如何重写hashCode()和equals()方法
接下来自己的理解:
1、首先java中set 、HashMap貌似包括List等底层的存储都会把,存储区域分成n个部分,而具体存在哪个部分是由hashcode决定的,也就是说查询的时候他会通过hashcode 所有小查询范围,所以如果所有的hashcode都一样,你的hashcode返回了一个常量 ,那么结果就是存储进去以后 都存放在一个区域,查询的时候变成了一个链式查询,完全没有效率。
2、如果你的hashcode返回的是一个随机数,或者不去重写hashcode,那么即使两个对象是一样的,也会出现问题。举个例子(应用自上面的博客):
我们先创建2个新的Coder对象:
Coder c1 = new Coder("bruce", 10); 02. Coder c2 = new Coder("bruce", 10);
假定我们已经重写了Coder的equals()方法而没有重写hashCode()方法:
@Override 02. public boolean equals(Object other) { 03. System.out.println("equals method invoked!"); 04. 05. if(other == this) 06. return true; 07. if(!(other instanceof Coder)) 08. return false; 09. 10. Coder o = (Coder)other; 11. return o.name.equals(name) && o.age == age; 12. }
然后我们构造一个HashSet,将c1对象放入到set中:
Set<Coder> set = new HashSet<Coder>(); set.add(c1);
最后:
System.out.println(set.contains(c2));
我们期望contains(c2)方法返回true, 但实际上它返回了false.
c1和c2的name和age都是相同的,为什么我把c1放到HashSet中后,再调用contains(c2)却返回false呢?这就是hashCode()在作怪了.因为你没有重写hashCode()方法,所以HashSet在查找c2时,会在不同的bucket中查找.比如c1放到05这个bucket中了,在查找c2时却在06这个bucket中找,这样当然找不到了.因此,我们重写hashCode()的目的在于,在A.equals(B)返回true的情况下,A, B 的hashCode()要返回相同的值.
接下来就是重写hashcode的时候会用31这个数 一般写法:
@Override 02. public int hashCode() { 03. int result = 17; 04. result = result * 31 + name.hashCode(); 05. result = result * 31 + age; 06. 07. return result; 08. }
我的理解是:首先为了尽量让产生hashcode保持唯一,所以一定使用一个素数来做系数(这里的31),但为什么是31而不是别的素数呢,因为:
31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化,使用31的原因可能是为了更好的分配hash地址,并且31只占用5bits!
所以从效率上 它是2的5次减1,对计算机来说2的乘除操作只需要做位移操作,例如*32就是左移5位。
也就是说31对计算机的角度来说运算更快、切占内存不多不少,而且形成惯例,虚拟机甚至都专门对他做了优化。所以常用31做系数算hashcode
以上理解来源于关于hashcode 里面 使用31 系数的问题的理解。
- 重写hashcode的原因 以及为啥用31的个人理解
- 重写hashcode和equals的原因探究
- toString、hashCode、equals的重写原因与重写示例
- 重写equals方法一般需要重写hashCode方法的原因
- 重写equals()方法就必须重写hashCode()方法的原因
- 个人--对重写equals与hashcode理解
- 黑马程序员--07.集合框架--02. 重写HashCode的内存变化过程以及两种重写hashCode方式的比较【个人总结】
- JAVA中重写自己的hashCode()方法原因
- 重写HashCode的内存变化过程以及两种重写hashCode方式的比较
- 重写了equals,为啥一定要重写hashcode
- HashCode的作用 以及重写equals方法为什么要重写HashCode方法?
- hashcode()的重写
- hashcode的重写方法
- Hashcode作用以及hash算法的理解
- hashCode()、equals()以及compareTo()方法的理解
- hashCode()、equals()以及compareTo()方法的理解
- hashCode()、equals()以及compareTo()方法的理解
- hashCode()、equals()以及compareTo()方法的理解
- Linux tree命令
- 使用Tomcat j_security_check实现用户登录、注销功能
- ajax在spring环境下,从前端jsp页面传送页面提交值到后端controller
- JavaScript学习指南之第一章Hello JavaScript!最基础的JavaScript入门
- TypeScript语法 中级篇
- 重写hashcode的原因 以及为啥用31的个人理解
- IOS应用内存释放机制
- 【转】gc日志分析工具
- Jmeter3.0发布,版本更新都更新了什么
- Linux下history命令用法
- 用Fiddler模拟低速网络环境
- jstack+top定位性能问题
- CentOS6.7搭建LNMP环境
- 前端之HTTP(一)