標籤:equals hashcode 對象相等 java
java中==、equals()、hashCode()都和對象的比較有關。
關於==
==是容易理解的。java設計java就是要比較兩個對象是不是同一個對象。
對於引用變數而言,比較的時候兩個引用變數引用的是不是同一個對象,即比較的是兩個引用中儲存的對象地址是不是一樣的。
對於基礎資料型別 (Elementary Data Type)而言,比較的就是兩個資料是不是相等,沒什麼歧義。
由於對於基礎資料型別 (Elementary Data Type)而言,沒有方法,所以不存在equal()和hashCode()的問題,下面的討論都是針對參考型別而言的。
關於equals()
為什麼java會設計equals()方法?
==比較的是兩個對象是否是同一個對象,這並不能滿足很多需求。有時候當兩個對象不==的時候,我們仍然會認為兩者是“相等”的,比如對於String對象,當兩個對象的字串序列是一直的,我們就認為他們是“相等”的。對於這樣的需求,需要equals()來實現。對於有這種需求的對象的類,重寫其equals()方法便可,具體的“相等”邏輯可以根據需要自己定義。
需要注意的地方
Object中equals()的預設實現是比較兩個對象是不是==,即其和==的效果是相同的。
java提供的某些類已經重寫了equals()方法。自己寫的類,如果需要實現自己的“相等”邏輯,需要重寫equals()方法。
關於hashCode()
為什麼會設計hashCode()方法?
hashCode()方法返回的就是一個數值,我們稱之為hashCode吧。從方法的名稱上就可以看出,其目的是產生一個hash碼。hash碼的主要用途就是在對對象進行散列的時候作為key輸入,據此很容易推斷出,我們需要每個對象的hash碼儘可能不同,這樣才能保證散列的存取效能。事實上,Object類提供的預設實現確實保證每個對象的hash碼不同(在對象的記憶體位址基礎上經過特定演算法返回一個hash碼)。
分析到這個地方,看似沒什麼問題,三者的作用很清晰,好像他們之間也沒什麼關係。在java的規範上,hashCode()方法和equals()方法確實可以沒有關係。
但是!!!!!!!!有一個問題。
問題如下:對於集合類HashSet、HashMap等和hash有關的類(以HashSet為例),是通過hash演算法來散列對象的。對HashSet而言,存入對象的流程為:根據對象的hash碼,經過hash演算法,找到對象應該存放的位置,如果該位置為空白,則將對象存入該位置;如果該位置不為空白,則使用equals()比較該位置的對象和將要入的對象,如果兩個相等,則不再插入,如果不相等,根據hash衝突解決演算法將對象插入其他位置。
而java規定對於HashSet判斷是不是重複對象就是通過equals() 方法來完成,這就需要在兩個對象equals()方法相等的時候,hash碼一定相等(即hashCode()返回的值相等)。假設兩個對象equals()方法相等的時候,hash碼不相等,會出現equals()相等的兩個對象都插入了HashSet中,這時不允許的。從而我們有了一下的結論:
結論:對於equals()相等的兩個對象,其hashCode()返回的值一定相等
java中的==、equals和hashCode區別