簡體   English   中英

Java中的哈希鍵

[英]Hashing Keys in Java

在Java中,當我使用字符串作為Hashmap的鍵時,與使用字符串哈希碼作為HashMap的鍵時,得到的結果略有不同。

有見識嗎?

當我使用字符串哈希碼作為HashMap中的鍵時。

不得使用哈希碼本身作為密鑰。 哈希碼並不是唯一的-完全允許兩個不相等的值具有相同的哈希碼。 您應該使用字符串本身作為鍵。 然后,映射將首先比較哈希碼(以快速縮小候選匹配項的范圍),然后與equals進行比較,以實現真正的字符串相等性。

當然,這是假設您的代碼確實符合您的問題,例如

HashMap<String, String> goodMap = new HashMap<String, String>();
goodMap.put("foo", "bar");

HashMap<Integer, String> badMap = new HashMap<Integer, String>();
badMap.put("foo".hashCode(), "bar");

如果您的代碼確實如此,則只需使用HashMap<String, String>

Object.hashCode()的文檔中(重點是我):

hashCode的一般約定為:

  • 在Java應用程序的執行過程中,只要在同一對象上多次調用它,則hashCode方法必須一致地返回相同的整數,前提是未修改該對象的equals比較中使用的信息。 從一個應用程序的執行到同一應用程序的另一執行,此整數不必保持一致。
  • 如果根據equals(Object)方法,兩個對象相等,則在兩個對象中的每個對象上調用hashCode方法必須產生相同的整數結果。
  • 根據equals(java.lang.Object)方法,如果兩個對象不相等,則不需要在兩個對象中的每個對象上調用hashCode方法必須產生不同的整數結果。 但是,程序員應該意識到,為不相等的對象生成不同的整數結果可能會提高哈希表的性能。

當然。 不同的字符串可以具有相同的hashCode,因此,如果將兩個這樣的字符串作為鍵存儲在映射中,則將有兩個條目(因為字符串不同)。 如果您將其hashCode用作鍵,則將只有一個條目(因為它們的hashCode相同)。

hashCode不能用來判斷兩個鍵是否相等。 它僅用於為密鑰分配存儲桶。 找到存儲桶后,會將存儲桶中包含的每個密鑰與帶有等號的新密鑰進行比較,如果找不到相等的密鑰,則將該密鑰添加到存儲桶中。

問題是,即使兩個對象不同,也不意味着它們的哈希碼也不同。

兩個不同的對象可以共享相同的哈希碼。 因此,您不應該將它們作為HashMap密鑰。

另外,由於從Object.hashCode()方法返回的哈希碼的類型為int ,因此只能具有2^32不同的值。 因此,對於不同的對象,您將取決於散列算法而產生“沖突”。

簡而言之: -

!obj.equals(obj1)不能確保obj.hashCode() != obj1.hashCode()

HashCodes可以對於相同的String相同或不同,因此要小心。 也許這就是為什么您獲得不同的結果。

這是另一個SO問題 請參閱Jon Skeet接受的答案。

僅當哈希函數是完美的哈希( 例如,請參見GPERF )時,才可以將哈希碼用作鍵。 只要關鍵對象不駐留在內存中,就可以節省內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM