为什么重写equals方法必须重写hashcode方法?
Posted qiuzhou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么重写equals方法必须重写hashcode方法?相关的知识,希望对你有一定的参考价值。
首先,我们先了解一下Object中的equals方法:
public boolean equals(Object obj)
对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true;
即object类中的equals方法其实判断的不是值是否相等,而是必须是同一个对象才会返回true。
假如自定义一个类,如果不重写equals,由于Object类是所有类的父类,调用equals时判断的是对象的引用是否指向同一块内存地址,而重写的目的是为了比较两个对象的value值是否相等。
接下来说说hashcode方法:
hashCode()方法:
此方法返回对象的哈希码值,什么是哈希码?
哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。
hashcode是用于散列数据的快速存取,当利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。
简单理解就是一套算法算出来的一个值,且这个值对于这个对象相对唯一。所以如果两个对象相等,他们的hashcode一定相等。反正则不一定。
要说清楚为什么重写equals方法必须重写hashcode方法,需要先了解一下集合中是如何检查重复元素?
当你把对象加? HashSet时,HashSet 会先计算对象的 hashcode 值来判断对象加?的位置,同时也会与该位置其他已经加?的对象的 hashcode 值作比较,如果没有相符的 hashcode,HashSet 会假设对象没有重复出现。
但是如果发现有相同 hashcode 值的对象,这时会调? equals() ?法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加?操作成功。如果不同的话,就会重新散列到其他位置。
所以当equals方法被重写时,需要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:
(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false
假如不重写会出现什么情况呢?
如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但不重写hashcode
那么我们当再new一个新的对象时,当原对象.equals(新对象)等于true时,此时两者的hashcode却是不一样的,这就会出现以下问题:
当我们把这个对象加入到存储散列集合中时(如Set类),将会存储了两个值一样的对象,导致混淆,因此,就也需要重写hashcode()
以上是关于为什么重写equals方法必须重写hashcode方法?的主要内容,如果未能解决你的问题,请参考以下文章