回答
當我使用字符串散列碼作爲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(Object)方法相等,則對這兩個對象中的每個對象調用hashCode方法必須產生相同的整數結果。
- 根據equals(java.lang.Object)方法,如果兩個對象不相等,則不要求對這兩個對象中的每個對象調用hashCode方法必須產生不同的整數結果。但是,程序員應該意識到,爲不等對象生成不同的整數結果可能會提高散列表的性能。
當然。不同的字符串可以有相同的hashCode,所以如果你在地圖中存儲兩個這樣的字符串作爲鍵,你將有兩個條目(因爲字符串不同)。 Whareas如果使用他們的hashCode作爲關鍵字,那麼只會有一個條目(因爲它們的hashCode是相同的)。
hashCode不用於判斷兩個鍵是否相等。它僅用於將密鑰分配給一個存儲桶。一旦找到桶,桶中包含的每個密鑰將與等於的新密鑰進行比較,如果找不到相同的密鑰,則會將密鑰添加到桶中。
感謝所有的答案。我試圖避免將密鑰存儲爲字符串,因爲它會消耗更多的內存! – user1785771
不要在沒有測量的情況下跳到這個結論。爲什麼會使用更多的內存?地圖不會複製密鑰。它只是使用對密鑰的引用。 –
我知道。但是,當我有超過兩百萬條記錄,然後存儲他們的字符串鍵會有很大的不同! @JB – user1785771
問題是,即使兩個對象不同,並不意味着它們的哈希碼也不同。
兩個不同的對象可以共享相同的哈希碼。所以,你不應該把它們當作一個HashMap鍵。
另外,由於從Object.hashCode()
方法返回的散列碼的類型爲int
,因此只能有2^32
不同的值。這就是爲什麼你會因爲不同的對象而產生「碰撞」,這取決於哈希算法。
簡而言之: -
!obj.equals(obj1)
不保證obj.hashCode() != obj1.hashCode()
。
我會在最後一行使用'!obj.equals(obj1)',因爲這是最重要的部分。 –
@JonSkeet。是啊,沒錯。編輯。謝謝 :) –
HashCodes
對於相同的字符串可以相同或不同,所以要小心。可能這就是你得到不同結果的原因。
這是another SO question就可以了。見Jon Skeet接受的答案。
您可以使用的哈希碼僅如果散列函數是一個完美的哈希鍵(見例如GPERF)。只要你的關鍵對象不駐留在內存中,你是正確的,你將節省內存。
- 1. Java:散列表和鍵集的問題()
- 2. 在Java中散列
- 3. Java中的CRC32散列
- 4. 鍵控散列和非鍵控散列之間的區別?
- 5. 如何通過散列的Perl散列中的值訪問鍵?
- 6. 什麼是Java 8中的字符串鍵的替代散列?
- 7. 打印散列鍵
- 8. 訪問perl中散列哈希散列的特定鍵?
- 9. Redis通過散列值中的模式刪除散列鍵
- 10. 通過散列值替換散列中的鍵
- 11. 散列中的鍵的數量
- 12. 在Java中散列對象?
- 13. Java MD5散列不匹配C#散列
- 14. Puppet中的訪問Facter散列鍵
- 15. perl中的散列鍵迭代
- 16. 散列的perl散列 - 對於eacy鍵組的內部鍵和相應的值
- 17. 如何根據散列中的所有鍵匹配另一個散列來從陣列中移除散列
- 18. 基於特定鍵的散列陣列
- 19. 的HashMap java中無法散列的MyObject
- 20. XMLSimple解析鍵值散列
- 21. 使用散列鍵和值
- 22. 鍵控或鹽漬散列?
- 23. 配對作爲散列鍵
- 24. 添加散列鍵值
- 25. 散列鍵URL參數?
- 26. 如何刪除散列值爲空的散列鍵?
- 27. Java - 如何遍歷散列表列表的散列圖
- 28. 如何在java中使用散列函數來散列密碼?
- 29. 從Java中的散列表填充JTable
- 30. Java ME中的MD5密碼散列
你能更具體嗎?在你面臨這個問題的地方顯示一些代碼片段。 –
爲什麼你期待一個不同的關鍵產生相同的結果?它不會。 – EJP