簡體   English   中英

Hashtable與HashMap中的哈希函數?

[英]Hashing function in Hashtable vs. HashMap?

我知道Hashtable和HashMap之間的區別。 但是,這兩個類似乎都在使用哈希函數來完成工作。 Hashtable中使用的哈希函數和HashMap中使用的哈希函數之間有區別嗎?

特別是,他們使用的散列算法有區別嗎? 在這兩個類中使用哈希的公式是什么?

換句話說,計算索引(哈希值)的方式是不同的?

特別是,他們使用的散列算法有區別嗎? 在這兩個類中使用哈希的公式是什么?

將對象用作哈希表鍵時使用的主哈希函數是對象的hashCode()方法。 實現一個像樣的哈希函數是關鍵類。

HashtableHashMap類獲取密鑰的哈希碼值並將其轉換為主哈希表數組鏈中的索引。 但是,在HashtableHashMap之間發生這種情況有所不同。

  • 對於Hashtable (Java 8),代碼是這樣的:

      hash = key.hashCode(); index = (hash & 0x7FFFFFFF) % tab.length; 
  • 對於HashMap (Java 8),代碼是(有效地):

      // (I have restructured the code for ease of comparison.) int h; hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); index = (tab.length - 1) & hash; 

如您所見, HashMap正在加擾密鑰哈希碼函數返回的哈希碼值。 這在源代碼中解釋如下:

[此方法]計算key.hashCode()並將更高位的散列擴展(XOR)降低。 因為該表使用2次冪掩蔽,所以僅在當前掩碼之上的位中變化的散列組將始終發生沖突。 (在已知的例子中是一組Float鍵,在小表中保存連續的整數。)因此我們應用一個向下傳播高位比特影響的變換。 速度,效用和比特擴展質量之間存在權衡。 因為許多常見的哈希集合已經合理分布(因此不會受益於傳播),並且因為我們使用樹來處理容器中的大量沖突,所以我們只是以最便宜的方式對一些移位的位進行異或,以減少系統損失,以及由於表格邊界而包含最高位的影響,否則這些位將永遠不會用於索引計算。

筆記:

  1. & vs %差異是因為在Hashtable中哈希數組大小是素數,但在HashMap (Java 8)中,大小是2的冪。

  2. 在Java 8 HashMap ,如果密鑰類實現Comparable ,則實現將把長哈希鏈轉換為二叉樹。

  3. HashMap處理null鍵,但Hashtable不處理。


但是,如果您的密鑰類具有設計糟糕/實現的hashCode()方法......或者有人故意設計哈希沖突,那么HashMap所有這些額外的復雜性才會發揮作用。

換句話說,如果你的關鍵類設計得很好,那么差異就不重要了

java.util.Hashtable<K,V>java.util.Vector<T>類似。 它是在開發早期就添加到SDK中的類,已被HashMap<K,V> ArrayList<T>取代(如ArrayList<T>取代Vector<T> )。

所以你根本不應該使用它,除非你需要默認使用Hashtable的所有操作的隱式同步,但是你可以為此目的使用Collections.synchronizedMap或者ConcurrentHashMap<K,V>

正如Javadoc所述:

從Java 2平台v1.2開始,這個類被改進以實現Map接口,使其成為Java Collections Framework的成員。 與新的集合實現不同, Hashtable是同步的。 如果不需要線程安全實現, 建議使用HashMap代替Hashtable 如果需要線程安全的高度並發實現,那么建議使用ConcurrentHashMap代替Hashtable

兩個類的散列應該是相同的,因為它們都使用int Object::hashCode來實現它們的目的。

暫無
暫無

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

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