簡體   English   中英

有關java.util.Hashtable的實現細節的查詢

[英]Queries regarding the implementation details of java.util.Hashtable

關於如何實現java.util.Hashtable,我有以下查詢。 這些是低級查詢,與Hashtable的使用無關,只與設計人員如何選擇實現數據結構有關

  • Hashtable的默認大小為11個桶。 11有什么特別之處? 為什么不10? 雖然我傾向於認為這只是一個神奇的數字,但我認為不太好
  • 要計算存儲桶編號,為什么我們不直接使用傳入的密鑰對象的哈希碼。 在實現中,我們實際上將桶號計算為(hashcode&7FFFFFFF)%table size,其中hashcode是輸入鍵的返回值,默認情況下表大小為11。 為什么我們重新編寫哈希碼本身? 難道它只是哈希碼%表大小?
  • contains(Object value)方法搜索哈希表中是否存在值。 為此,我們從最后一個桶順序搜索並向第一個桶移動。 這只是采用的開發者風格嗎? 哈希表只是一個鏈表的數組。 更直觀地說,我希望搜索從第一個桶移動到最后一個桶,但不然發現了。 我知道功能上兩者都是一樣的。 但還有其他原因嗎?
  • 最大數組大小(在重新散列期間使用)設置為Integer.MAX - 8. 8這里有什么意義?
  1. 它似乎是一個經驗值,涉及在使用太多空間和浪費時間的重復操作之間進行權衡。 Hashtable javadocs

初始容量控制了浪費空間和重新運算操作的需要之間的權衡,這是非常耗時的。 如果初始容量大於Hashtable將包含的最大條目數除以其加載因子,則不會發生重復操作。 但是,將初始容量設置得太高會浪費空間。

  1. 該值使用0x7FFFFFFF進行位掩碼,以刪除將使值為負的第一個位。 這會強制該值為非負值,因此%操作后的結果索引也將為非負值。 這對於在內部桶陣列中產生可行索引是必要的。

  2. 這可能是為了略微提高性能。 本文聲稱向后循環確實如此。

結果表明,在100萬個數據中,正向和反向循環之間沒有太大差異。 然而,當數據變得龐大時,反向循環的性能比前向循環的性能略快15%左右。

我不知道這是否真的如此,但這可能是動機。

  1. 我的源代碼揭示了用於最大數組大小的私有常量上的Javadocs。
/**
 * The maximum size of array to allocate.
 * Some VMs reserve some header words in an array.
 * Attempts to allocate larger arrays may result in
 * OutOfMemoryError: Requested array size exceeds VM limit
 */
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

我不知道現在有多有效,但這是為了避免意外的OutOfMemoryError

#1:AndreyS在評論中回答: 為什么Hashtable的initialCapacity為11而HashMap中的DEFAULT_INITIAL_CAPACITY為16且需要2的冪

#2:在計算模數之前確保數字為正數。 否則結果可能是負面的,我們將超出界限。

#3:我必須猜測,當反向循環時,你只評估一次長度,並與常量(0)進行比較,並在常規循環中與變量進行比較。 我不知道這是否是他們心中的想法,但這可能是一個考慮因素。

#4:為避免rehash()中的整數溢出:

int i = table.length;
Entry[] arrayOfEntry1 = table;
int j = (i << 1) + 1;
if (j - 2147483639 > 0)
{
  if (i == 2147483639) {
    return;
  }
  j = 2147483639;
}

暫無
暫無

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

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