[英]Java: get a unique property of an object (like hashcode, but collision proof)
[英]Is there a way to get Java's unique hashcode from objects like HashMap?
我相信,如果我聲明一個HashMap並重復提供它的Map.Entry實例,最終哈希碼將與另一個哈希碼沖突,即使這兩個鍵(碰巧是我的需要的字符串)是不同的。
此時,HashMap和其他使用散列的類將生成不同的哈希代碼,作為內部使用的真正密鑰。 (編輯:事實證明這不是真的。請看選定的答案。)
有沒有辦法獲得內部密鑰? 我想要它的原因是因為32位密鑰比真實世界密鑰更有效的內存和速度,這將是(可能)長字符串。
我可以為我的字符串創建一個哈希代碼注冊表,但是如果Java已經可以做到這一點,為什么還要煩惱。
不 。 您無法為系統中的每個可能對象獲取唯一的32位數。
最簡單的證明是,在具有足夠內存量的64位JVM上,您可以輕松擁有超過2 ^ 32個對象:因此您需要超過2 ^ 32個不同的哈希值。 但由於您只有32位來存儲這些哈希值,因此您不能獲得超過2 ^ 32個不同的哈希值。 這被稱為Pidgeonhole原理 。
另外: HashMap
不會產生“唯一的哈希碼”:它只是將具有相同哈希碼的所有元素存儲在同一個桶中(在鏈表中),並且如果必須檢索一個,則使用equals()
檢查它們中的每一個那些。
強制性鏈接: 哈希表 -只有極個別情況下,甚至允許最小完美哈希 ,這不包括一般的哈希表像HashMap
。 實際上有兩個因素與鴿子洞原則有關 :
int
表示的唯一對象:因此, 哈希值不能保證唯一。 也就是說,散列函數的范圍小於唯一對象的域。 bucket_used = hash % bucket_count
。 (對於42個條目,具有2 ^ 32個桶的哈希表幾乎不可行;在這種情況下,哈希值的域(如果它大於桶計數)在很大程度上是不相關的。) (此外, 哈希代碼與對象相等性具有嚴格的關系 ,如果每個對象確實具有“唯一系統哈希代碼”,則所述哈希代碼可用於對象身份映射, 但不能用於對象相等性映射 。)
由於這些原因,在一般的散列表實現中總是需要 沖突解決 。 (OpenJDK 7 HashMap實現使用鏈接列表鏈接方法,最終相等性由==
和equals()
按順序決定。)
雖然JDK實現確實使用內部“哈希混合器” ,目的是創建更好的哈希值分布,但這與哈希表如何處理沖突無關,並且與原始哈希函數一樣,受上述相同規則的約束。 。
快樂的編碼。
不,它不會產生不同的哈希碼。 它將使用相同的哈希碼維護多個條目,並且可以輕松地查找具有相同哈希碼的所有條目。 當您嘗試使用該哈希代碼查找密鑰時,它將檢查與所有哈希匹配密鑰的相等性,直到找到相等匹配或用完為止。 閱讀HashMap
的代碼以了解更多詳細信息。
當可以有超過2 32個不同的對象時,你會如何期望HashMap
產生一個真正獨特的int
哈希?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.