初识 对象与hashCode
hashCode 是什么。
官方规定:
![](https://img.haomeiwen.com/i9661340/ce11784a48af967f.png)
其实 通俗点 来讲,hashCode 将 对象的内存地址转化为一个 数字返回。然后有几个 规范:
【1】 两个对象的equals 相等 则他们的hashCode 一定相等。 (注意:这里讲得equals 只是 Object 的 方法,不是其子类覆写的方法)
【2】两个对象的equals 不相等,则hashCode 不一定相等。(其实大部分都是不相等的,只有一少部分会相等,因为设计的hashCode 规范,最好保证不同的对象返回不通的 hashCode,以来提高hash表性能)
【3】 hsahCode 不相等,对象equals 一定不相等。
【4】 hsahCode 相等,对象可能相等,也可能不想等。
那里用到hashCode
对于集合里的list 和数组来说,其实 hashCode作用 几乎可以无视了。 主要是我们使用HashMap HashTable HashSet 之类的时候。
为什么以上集合可以判断该对象已经插入进来呢?
我们可以通过 obj.equals,来确定对象的唯一性,但是,数据量上去的时候,就会进行很多次的比较,比较麻烦。 hashCode 的出现就是解决这个问题。
当我们将一个对象插进去集合时,先会调用该对象的hashCode 方法,来判断该对象是否在这个集合里。如过不在该集合里,则直接存进去,不进行任何比较。有一个table来存储该集合所有对象的hashCode值。如果存在,则先比较equals 是否相等,如果相等,则抛出去,不存储。如果不相等,则散列到其他地方,所以可能存在不同对象的hashCode 是相同的,也引出了一个地址冲突(是不是可以说,一个hashCode 存了多个不同对象)。
![](https://img.haomeiwen.com/i9661340/a350f28532a67ffb.png)
我们分析 如下:
当执行到 第 33 行时,new HashObj() 代码被执行,先去map的table里去查找该对象的hashCode 是否存在,发现没有存在,则不在执行equals 方法。打印 执行 hashCode。
当执行到 第 34 行时,new HashObj() 代码被执行,发现 map的table 已经有了 hashCode ==1 的值,所以要在去equals一下,所以执行顺序是
执行 hashCode ==》 执行 equals。 (我在这里重写了 object的 hashCode 方法 和equals 方法,所有 的hashCode 都是1。)
hashCode与equals
当我们重写一个 对象的 equals 方法时,一定要重写他的 hashCode 方法。 为什么?
![](https://img.haomeiwen.com/i9661340/389d2a78dfc62892.png)
看这段代码。 我们定义 当对象的名字和年龄相同时,则对象是一个人。
但是如果我们不去重写 对象的hashCode 方法时,在执行第23行代码时,最后的打印是个 null。原因很简单了,一个p1 ,一个p2,对应的hashCode肯定是不相同的,所以map 去自己的table 表里拿相应应记录时,用的是两个不同的hashCode,所以拿不到。
但是我们对象的属性完全相同,这应该就是同一个对象才对,我们的本意应该就是让该对象可以拿得到。
这个时候只要让对象的hashCode可以在保持相等。
我们对象返回的hashCode 就是基于自己属性和位置的一个int 值。
最后只要重写我们的hashCode ,如上。就可以了。
参考博文 : http://myhadoop.iteye.com/blog/2059833
http://www.importnew.com/20381.html
http://blog.csdn.net/fenglibing/article/details/8905007
https://www.cnblogs.com/dolphin0520/p/3681042.html