hashcode()和equals()方法详解
1、何为hashcode()
hash是一个函数,就是通过一种算法来得到一个hash值。通过hash算法得到的hash值就存放在这张hash表中,也就是说hash表示所有的hash值组成的。hashcode通俗地讲就是在hash表中对应的位置。
每个对象都有hashcode,对象的hashcode是怎么来的呢?首先一个对象肯定有物理地址,独享的物理地址跟这个hashcode地址不一样,hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址,那么对象如何得到hashcode呢?通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode,所以,hashcode是什么呢?就是在hash表中对应的位置。这里如果还不是很清楚的话,举个例子,hash表中有 hashcode为1、hashcode为2、(…)3、4、5、6、7、8这样八个位置,有一个对象A,A的物理地址转换为一个整数17(这是假如),就通过直接取余算法,17%8=1,那么A的hashcode就为1,且A就在hash表中1的位置。
2、为什么需要hashcode()方法,他有什么好处
当我们在集合中,如果该集合元素不可重复,怎么来保证和判断呢?这就是Object.equals方法。每次添加一个新的元素的时候都要和已插入元素用该方法来比较他们是否相等,当已插入数据较大时,如已经有1000个元素了,在插入第1001个元素的时候,我们就要调用1000次equals方法,大大降低了效率。于是,Java采用了哈希表的原理。可以简单的理解为hashCode方法返回的是对象存储的物理地址(实际可能不是)。这样一来,当添加新的元素的时候,先调用hashCode方法,就一下子能定位到它应该放的物理位置。如果这个位置没有元素,他就可以直接放在这个位置上,不用再进行任何比较;如果这个位置已经有元素了,这才调用equals方法与新元素进行比较,相同的话就不存了,不相同的话就散列其他地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。
3、hashcode()和equals()方法的关系
通过前面这个例子,大概可以知道,先通过hashcode来比较,如果hashcode相等,那么就用equals方法来比较两个对象是否相等,用个例子说明:上面说的hash表中的8个位置,就好比8个桶,每个桶里能装很多的对象,对象A通过hash函数算法得到将它放到1号桶中,当然肯定有别的对象也会放到1号桶中,如果对象B也通过算法分到了1号桶,那么它如何识别桶中其他对象是否和它一样呢,这时候就需要equals方法来进行筛选了。
Java 对于eqauls 方法和hashCode 方法是这样规定的:
1、如果两个eqauls相同,那么它们的hashCode 值一定要相同;
2、如果两个对象的hashCode 相同,它们的eqauls并不一定相同
4、为什么equals方法重写的话,建议也一起重写hashcode方法?
举个例子,其实就明白了这个道理,
比如:有个A类重写了equals方法,但是没有重写hashCode方法,看输出结果,对象a1和对象a2使用equals方法相等,按照上面的hashcode的用法,那么他们两个的hashcode肯定相等,但是这里由于没重写hashcode方法,他们两个hashcode并不一样,所以,我们在重写了equals方法后,尽量也重写了hashcode方法,通过一定的算法,使他们在equals相等时,也会有相同的hashcode值。
实例:现在来看一下String的源码中的equals方法和hashcode方法。这个类就重写了这两个方法,现在为什么需要重写这两个方法了吧?
equals方法:其实跟我上面写的那个例子是一样的原理,所以通过源码又知道了String的equals方法验证的是两个字符串的值是否一样。还有Double类也重写了这些方法。很多类有比较这类的,都重写了这两个方法,因为在所有类的父类Object中。equals的功能就是 ==号的功能。你们还可以比较String对象的这两者的区别啦。这里不再说明。
hashcode方法
5、为什么两个对象有相同的hashcode值,他们也不一定相等?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)