為什么重寫Equals方法要重寫HashCode方法
為什么重寫Equals方法要重寫HashCode方法
1.Equals的作用和重寫Equals需要遵循的規(guī)則
Equals的主要作用是判斷兩個對相是否相等, Object類是所有類的父類,因此每個對象都可以使用Object的Equals相比較:
? ?
Object類中equals方法比較的是兩個對象的引用地址,只有對象的引用地址指向同一個地址時,才認為這兩個地址是相等的,否則這兩個對象就不想等。
如果有兩個對象,他們需要的是這兩個對象相等,因此默認的equals()方法是不符合我們的要求的,這個時候我們就需要對equals()方法進行重寫以滿足我們的預(yù)期結(jié)果。
在java的集合框架中需要用到equals()方法進行查找對象,如果集合中存放的是自定義類型,并且沒有重寫equals()方法,則會調(diào)用Object父類中的equals()方法按照地址比較,往往會出現(xiàn)錯誤的結(jié)果,此時我們應(yīng)該根據(jù)業(yè)務(wù)需求重寫equals()方法。
重寫Equals方法需要遵循的規(guī)則
必須定義等價關(guān)系:自反、對稱、傳遞。自反性:對于任意的對象x,x.equals(x)返回true(自己一定等于自己);對稱性:對于任意的對象x和y,若x.equals(y)為true,則y.equals(x)亦為true;傳遞性:對于任意的對象x、y和z,若x.equals(y)為true且y.equals(z)也為true,則x.equals(z)亦為true;
除非對象被修改,否則調(diào)用多次equals應(yīng)為同樣結(jié)果:對于任意的對象x和y,x.equals(y)的第一次調(diào)用為true,那么x.equals(y)的第二次、第三次、第n次調(diào)用也均為true,前提條件是沒有修改x也沒有修改y;
對于非空引用x,x.equals(null)永遠返回為false。
2.重寫hashcode的原因及重寫hashCode()方法需要遵循的協(xié)定
1.什么是hashcode
hashcode是一個數(shù)值,主要作用是散列數(shù)據(jù)的快速存儲, Object類是所有類的父類,因此每個對象都可以使用Object的hashcode()得到對應(yīng)的hash值:
? ?
hashCode()方法用于散列數(shù)據(jù)的快速存儲,HashSet/HashMap/Hashtable類存儲數(shù)據(jù)時都是根據(jù)存儲對象的hashcode值來進行分類存儲的,一般先根據(jù)hashcode值在集合中進行分類,在根據(jù)equals()方法判斷對象是否相同。
HashMap對象是根據(jù)其Key的hashCode來獲取對應(yīng)的Value。
生成一個好的hashCode值能提高HashSet查找的性能,差的hashCode值不但不能提高性能,甚至可能造成錯誤。比如hashCode方法中返回常量,會讓,HashSet的查找效率退化為List集合的查找效率;hashCode方法中返回隨機數(shù),會讓查找結(jié)果變的不可預(yù)測。
好的hashCode生成方式是讓對象中的關(guān)鍵屬性與質(zhì)數(shù)相乘,并將積相加獲取。
2.重寫hashcode方法的原因:
為了維護hashCode()方法的equals協(xié)定,該協(xié)定指出:如果根據(jù) equals()方法,兩個對象是相等的,那么對這兩個對象中的每個對象調(diào)用 hashCode方法都必須生成相同的整數(shù)結(jié)果;而兩個hashCode()返回的結(jié)果相等,兩個對象的equals()方法不一定相等。
HashMap對象是根據(jù)其Key的hashCode來獲取對應(yīng)的Value。
在重寫父類的equals()方法時,也重寫hashcode()方法,使相等的兩個對象獲取的HashCode值也相等,這樣當此對象做Map類中的Key時,兩個equals為true的對象其獲取的value都是同一個,比較符合實際。
3.重寫hashCode()方法需要遵循的協(xié)定
一致性:在Java應(yīng)用程序執(zhí)行期間,在對同一對象多次調(diào)用hashCode方法時,必須一致地返回相同的整數(shù),前提是將對象進行hashcode比較時所用的信息沒有被修改。
equals:如果根據(jù)equals()方法比較,兩個對象是相等的,那么對這兩個對象中的每個對象調(diào)用hashCode()方法都必須生成相同的整數(shù)結(jié)果,等價對象必須有相同的hashcode。注:這里說的equals()方法是指Object類中未被子類重寫過的equals()方法。
如果根據(jù)equals()方法比較,兩個對象不相等,那么對這兩個對象中的任一對象上調(diào)用hashCode方法不一定生成不同的整數(shù)結(jié)果。但是,程序員應(yīng)該意識到,為不相等的對象生成不同整數(shù)結(jié)果可以提高哈希表的性能。
示例代碼
學生類: Student.java
測試類: EqualsAndHashcode.java
【附】
github代碼下載地址:? ?https://github.com/yysgit/JavaProject
【參考資料】
https://blog.csdn.net/qq_45830276/article/details/126615786
https://baijiahao.baidu.com/s?id=1746705951468143428&wfr=spider&for=pc
https://blog.csdn.net/wdnn_wza/article/details/125075525
https://blog.csdn.net/WinnerBear/article/details/126068645