簡體   English   中英

有沒有辦法從像HashMap這樣的對象中獲取Java的唯一哈希碼?

[英]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 實際上有兩個因素與鴿子洞原則有關

  1. 正如其他人所說,可能有更多的對象,而不是用int表示的唯一對象:因此, 哈希值不能保證唯一。 也就是說,散列函數的范圍小於唯一對象的域。
  2. 散列表中使用的桶的數量[顯着]小於散列值的域:這導致無法保證使用唯一的桶 :通常, 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.

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