[英]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.