hash code、equals和「==」三者的關係

兩個對象值相同(x.equals(y) == true),則必定有相同的hash code。java

 

這是java語言的定義: c++

由於:Hash,通常翻譯作「散列」,也有直接音譯爲"哈希"的,就是把任意長度的輸入(又叫作預映射, pre-image),經過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間一般遠小於輸入的空間,不一樣的輸入可能會散列成相同的輸出,而不可能從散列值來惟一的肯定輸入值。
1) 對象相等則hashCode必定相等;
2) hashCode相等對象未必相等。面試

 

== 是比較地址是否相等,JAVA中聲明變量都是引用嘛,不一樣的引用,可能指向同一個地址。

equals 是比較值是否相等。

這種題很容易在面試中被問到。。。算法

 

hash code、equals和「==」三者的關係翻譯

 

1.若是是基本變量,沒有hashcode和equals方法,基本變量的比較方式就只有==,;

2.若是是變量,因爲在java中全部變量定義都是一個指向實際存儲的一個句柄(你能夠理解爲c++中的指針),在這裏==是比較句柄的地址(你能夠理解爲指針的存儲地址),而不是句柄指向的實際內存中的內容,若是要比較實際內存中的內容,那就要用equals方法,可是!!!

若是是你本身定義的一個類,比較自定義類用equals和==是同樣的,都是比較句柄地址,由於自定義的類是繼承於object,而object中的equals就是用==來實現的,你能夠看源碼。

那爲何咱們用的String等等類型equals是比較實際內容呢,是由於String等經常使用類已經重寫了object中的equals方法,讓equals來比較實際內容,你也能夠看源碼。

3. hashcode
在通常的應用中你不須要了解hashcode的用法,但當你用到hashmap,hashset等集合類時要注意下hashcode。

你想經過一個object的key來拿hashmap的value,hashmap的工做方法是,經過你傳入的object的hashcode在內存中找地址,當找到這個地址後再經過equals方法來比較這個地址中的內容是否和你原來放進去的同樣,同樣就取出value。

因此這裏要匹配2部分,hashcode和equals
但假如說你new一個object做爲key去拿value是永遠得不到結果的,由於每次new一個object,這個object的hashcode是永遠不一樣的,因此咱們要重寫hashcode,你能夠令你的hashcode是object中的一個恆量,這樣永遠能夠經過你的object的hashcode來找到key的地址,而後你要重寫你的equals方法,使內存中的內容也相等。。。指針

 

 

首先,從語法角度,也就是從強制性的角度來講,hashCode和equals是兩個獨立的,互不隸屬,互不依賴的方法,equals成立與hashCode相等這兩個命題之間,誰也不是誰的充分條件或者必要條件。  
   
  可是,從爲了讓咱們的程序正常運行的角度,咱們應當向Effective   Java中所言  
   
  重載equals的時候,必定要(正確)重載hashCode  
   
  使得equals成立的時候,hashCode相等,也就是a.equals(b)->a.hashCode()   ==   b.hashCode(),或者說此時,equals是hashCode相等的充分條件,hashCode相等是equals的必要條件(從數學課上咱們知道它的逆否命題:hashCode不相等也不會equals),可是它的逆命題,hashCode相等必定equals以及否命題不equals時hashCode不等都不成立。  
   
  因此,若是面試的時候,最好把hashCode與equals之間沒有強制關係,以及根據(沒有語法約束力的)規範的角度,應當作到...這兩層意思都說出來:P  code

 

 

  總結一下,equals()是對象相等性比較,hashCode()是計算對象的散列值,固然他們的依據是對象的屬性。對象

 對於equals,通常咱們認爲兩個對象同類型而且全部屬性相等的時候纔是相等的,在類中必須改寫equals,由於Object類中的equals只是判斷兩個引用變量是否引用同一對象,若是不是引用同一對象,即便兩個對象的內容徹底相同,也會返回false。固然,在類中改寫這個equals時,你也能夠只對部分屬性進行比較,只要這些屬性相同就認爲對象是相等的。  
   
  對於hashCode,只要是用在和哈希運算有關的地方,前面不少兄弟都提到了,和equals同樣,在你的類中也應該改寫。固然若是兩個對象是徹底相同的,那麼他們的hashCode固然也是同樣的,可是象前面所述,規則能夠由你本身來定義,所以二者之間並無什麼必然的聯繫。  
   
  固然,大多數狀況下咱們仍是根據全部的屬性來計算hashCode和進行相等性比較。繼承

相關文章
相關標籤/搜索