Java中覆蓋hashCode的約定和簡單方法

2021-08-30 16:45:52 字數 1428 閱讀 5169

object中關於hasdcode的通用約定:

1. 在應用程式的執行期間,只要物件的equals方法的比較操作所用到的資訊沒有被修改,那麼對這同乙個物件呼叫多次,hashcode方法都必須始終如一地返回同乙個整數。在同乙個應用程式的多次執行過程中,每次執行所返回的整數可以不一致。

2. 如果兩個物件根據equals(object)方法比較是相等的,那麼呼叫這兩個物件中任意乙個物件的hashcode方法都必須產生相同的整數結果。

3. 如果兩個物件根據equals(object)方法比較是不相等的,那麼呼叫這兩個物件中任意乙個物件的hashcode方法,則不一定要產生不同的整數結果。但是程式設計師應該知道,給不相等的物件產生截然不同的整數結果,有可能提高hash table的效能。

乙個好的雜湊函式通常傾向於「為不相等的物件產生不相等的雜湊碼」。理想情況下,雜湊函式應該把集合中不相等的例項均勻地分布到所有可能的雜湊值上。要想完全達到這種理想的情況是非常困難的。幸運的是,相對接近這種理想情形則並不太困難。下面給出一種簡單的解決辦法:

1. 把某個非零的常數值,比如說17,儲存在乙個名為result的int型別的變數中。

2. 對於物件中的每個關鍵域f (指quals方法中涉及的每個域),完成以下步驟:

a. 為該域計算int型別的雜湊碼c:

1) 如果該域是boolean型別,則計算(f ? 1 : 0)。

2) 如果該域是byte, char, short或者int型別,則計算(int)f。

3) 如果該域是long型別,則計算(int)(f^(f>>>32))。

4) 如果該域是float型別,則計算float.floattointbits(f)。

5) 如果該域是double型別,則計算double.doubletolongbits(f),然後按照步驟2.a.3,為得到的long型別值計算雜湊值。

6) 如果該域是乙個物件的引用,並且該類的equals方法通過遞迴地呼叫equals的方式來比較這個域,則同樣為這個域遞迴地呼叫hashcode。如果需要更複雜的比較,則為這個域計算乙個「正規化(canonical representation)」,然後針對這個正規化呼叫hashcode。如果這個域的值為null,則返回0 (或者其他某個整數,但通常是0)。

7) 如果該域是乙個陣列,則要把每乙個元素當作單獨的域來處理。也就是說,遞迴地應用上述規則,對每個重要的元素計算乙個雜湊碼,然後根據步驟2.b中的做法把這些雜湊值組合起來。如果陣列域中的每個元素都很重要,可以利用發行版本1.5中增加的其中乙個arrays.hashcode方法。

b. 按照下面的公式,把步驟2.a中計算得到的雜湊碼c合併到result中:

result = 31 * result + c;

3. 返回result。

4. 寫完了ashcode方法之後,問問自己「相等的例項是否都具有相等的雜湊碼」。要編寫單元測試來驗證你的推斷。如果相等的例項有著不同的雜湊碼,則要找出原因,並修正錯誤。

覆蓋equals總要覆蓋hashCode

1 通過物件位址,判斷兩個物件是否相等 public native int hashcode 2 equals 在沒有覆蓋object的equals之前,相當於 public boolean equals object obj 為什麼覆蓋equals總要覆蓋hashcode 1 equals應該提供...

JAVA中hashCode的編寫

1 把某個非零常數值,比如17,儲存在乙個叫result的int型別的變數中。2 對於物件中的關鍵域f 指equals方法中考慮的每乙個域 完成以下步驟 a 為該域計算int型別的雜湊碼c i 如果該域是boolean型別,則計算 f 0 1 ii 如果該域是byte char short或者int...

java中hashcode的理解

hashcode 是幹什麼用的?2008年09月29日 星期一 07 32 p.m.首先hashcode是雜湊演算法的一中簡單實現,他是乙個物件的雜湊嗎值。一般和equals一起使用。hashcode也是用來查詢的,如果你學過資料結構就應該知道,在查詢和排序這一章有 例如記憶體中有這樣的位置 0 1...