1. 程式人生 > >兩個物件值相同,有相同的hash code

兩個物件值相同,有相同的hash code

兩個物件值相同(x.equals(y) == true),則一定有相同的hash code。

這是java語言的定義: 

因為: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  

  總結一下,equals()是物件相等性比較,hashCode()是計算物件的雜湊值,當然他們的依據是物件的屬性。

 對於equals,一般我們認為兩個物件同類型並且所有屬性相等的時候才是相等的,在類中必須改寫equals,因為Object類中的equals只是判斷兩個引用變數是否引用同一物件,如果不是引用同一物件,即使兩個物件的內容完全相同,也會返回false。當然,在類中改寫這個equals時,你也可以只對部分屬性進行比較,只要這些屬性相同就認為物件是相等的。  
   
  對於hashCode,只要是用在和雜湊運算有關的地方,前面很多兄弟都提到了,和equals一樣,在你的類中也應該改寫。當然如果兩個物件是完全相同的,那麼他們的hashCode當然也是一樣的,但是象前面所述,規則可以由你自己來定義,因此兩者之間並沒有什麼必然的聯絡。  
   
  當然,大多數情況下我們還是根據所有的屬性來計算hashCode和進行相等性比較。