一文搞懂hashCode()和equals()方法的原理
Java中的超類java.lang.Object 有兩個非常重要的方法:
public boolean equals(Object obj) public int hashCode()
這兩個方法最開發(fā)者來說是十分重要的,必須清楚的理解,但實際上,甚至很多經(jīng)驗豐富的Java開發(fā)者有時候也沒有真正搞清楚這兩個方法的使用和原理。當我們自定義了對象,并且想要將自定義的對象加到Map中時,我們就必須對自定義的對象重寫這兩個方法,才能正確使用Map。我們接下來將用這篇文章指出在使用hashcode和equals方法時,經(jīng)常范的錯誤,并指出如何正確的使用這兩個方法,以及這兩個方法工作的原理。
常見的誤區(qū)
看下面這段代碼:
import java.util.HashMap; public class HashCodeEqual { public static void main(String[] args) { Apple a1 = new Apple("Blue"); Apple a2 = new Apple("Green"); HashMap<Apple, Integer> map = new HashMap<>(); map.put(a1, 10); map.put(a2, 20); System.out.println(map.get(new Apple("Green"))); } } class Apple { public String color; public Apple(String color) { this.color = color; } @Override public boolean equals(Object obj) { if(! (obj instanceof Apple)) return false; if(obj == this) return true; return this.color.equals(((Apple)obj).color); } }
我們執(zhí)行上面這段代碼
卻發(fā)現(xiàn)與我們預想的結(jié)果并不一樣,我們想取出map中顏色為Green的apple,最后卻得到一個null值,這說明map沒有我們需要的顏色為green的apple對象,但實際上,我們明明向其中添加了一個顏色為green的apple對象,也重寫了equals方法,為什么最后卻取不出這個對象呢?
![Upload Paste_Image.png failed. Please try again.]
錯誤出現(xiàn)的原因
這個問題引起的原因是因為我們沒有重寫“hashCode”方法,這就需要我們深入理解equals方法和hashCode方法的原理:
1 如果兩個對象是相等的,那么他們必須擁有一樣的hashcode,這是第一個前提
2 如果兩個對象有一樣的hashcode,但仍不一定相等,因為還需要第二個要求,也就是equals方法的判斷。
其實,map判斷對象的方法就是先判斷hashcode是否相等,如果相等再判斷equals方法是否返回true,只有同時滿足兩個條件,最后才會被認為是相等的。
Map查找元素比線性搜索更快,這是因為map利用hashkey去定位元素,這個定位查找的過程分成兩步,內(nèi)部原理中,map將對象存儲在類似數(shù)組的數(shù)組的區(qū)域,所以要經(jīng)過兩個查找,先找到hashcode相等的,然后在再在其中按線性搜索使用equals方法,通過這兩部來查找一個對象。
就像上圖這個結(jié)構(gòu),每個hashcode對應一個桶,每個tongli桶里還有多個對象,確定桶的方法是hashCode,在桶中遍歷線性查找的方法是equals。
在Object中的默認的hashCode方法的實現(xiàn)是為不同的對象返回不同的hashcode,因此如果我們不重寫hashcode方法,那么沒有任何兩個對象會是相等的,因為object類中的hashcode實現(xiàn)是為不同的對象返回不同的hashcode。
所以,我們就搞清楚了上一段代碼出錯的原因,由于沒有重寫hashcode方法,所有的對象都是不一樣的,所以我們需要重寫hashcode方法,讓顏色的對象的hashcode是一樣的,比較直接的寫法就是直接用color的length作為hashcode。
public int hashCode(){ return this.color.length(); }
** 切記,一定要同時重寫hashCode和equals方法 **
以上就是一文搞懂hashCode()和equals()方法的原理的詳細內(nèi)容,更多關于hashCode()和equals()方法的資料請關注腳本之家其它相關文章!
相關文章
Spring Boot動態(tài)加載Jar包與動態(tài)配置實現(xiàn)
隨著項目的不斷演進和業(yè)務需求的增長,很多場景下需要實現(xiàn)系統(tǒng)的動態(tài)性和靈活性,本文主要介紹了Spring Boot動態(tài)加載Jar包與動態(tài)配置實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-02-02Spring Cloud Zuul自定義過濾器的實現(xiàn)
這篇文章主要介紹了自定義Spring Cloud Zuul過濾器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03java jackson 將對象轉(zhuǎn)json時,忽略子對象的某個屬性操作
這篇文章主要介紹了java jackson 將對象轉(zhuǎn)json時,忽略子對象的某個屬性操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10Java實現(xiàn)規(guī)則幾何圖形的繪制與周長面積計算詳解
隨著計算機的發(fā)展,人們對圖形的計算要求會越來越高。在各行各業(yè)中的計算人員會對圖形的計算要有便利的要求,規(guī)則幾何圖形問題求解程序應運而生!本文將用Java編寫一個程序,可以實現(xiàn)規(guī)則幾何圖形的繪制與周長面積計算,感興趣的可以了解一下2022-07-07