注:JDK版本:1.8.0_251
首先,我們來看一下在Object類中,這兩個方法是是干嘛的,現貼出代碼:
在Object類中, equals方法進行相等比較,是用 == 號對兩個對象進行比較。我們知道,在Java中,==比較,如果不是基本數據類型的話,其實比較的是兩個對象的內存地址,
我們再看看Object類的hashCode()方法:
這個方法呢,它是一個native方法,這個方法會返回當前對象的哈希散列碼。
OK,現在打完了Object類的鋪墊,我們再來看看HashMap的containsKey()方法的源碼:
這個hash方法,是HashMap用來定位key所命中的bucket的位置。
比如說,我們定義如下一個User類:
現在我們來創建兩個User對象,這兩個User對象的每一個字段都完全一樣,我們要把User對象當作HashMap中的key進行存儲的話,那么我們看看它們的hashCode()方法的執行結果是否一樣?
顯然,它們的hashCode是不一樣的,接下來,那么將該對應作為HashMap的key,就會有問題了。因為我們希望這兩個對象命中同一個bucket,但事實上,這兩個對象因為hashcode的不一樣,而會命中不一樣的bucket。我們現在覆蓋一下User類的equals方法和hashCode方法:
覆蓋了這兩個方法之后,我們再執行上面的test代碼,我們再看看效果:
這個時候,他們的hascode也是一樣的了。
那有的人可能會說了,那我只覆蓋hashcode方法,不覆蓋equals方法,它不行嗎???好吧,那我們來看看HashMap的containsValue()方法的代碼:
前端我們提及過,containsValue方法調用的是Object.equals()方法,如果我們不去覆蓋它的話,它只會拿對象的地址進行比較,像上面User類這樣的需求,所有字段值完全相同的User對象,也就斷然不可能相等了。。。
因此,我們在對一個類的equals方法進行覆蓋的時候,通常情況下,我們會同時覆蓋equals方法和hashCode()方法。