[英]Java Hashmap Internal
我對Java HashMap
類幾乎沒有疑問。 這是我的理解
transient Entry[] table;
表數組將根據hashCode()
的值保存數據。 我需要知道這個數組何時初始化。 數組長度是基於我們在HashMap
初始化期間定義的容量還是默認容量16(如果在調用構造函數時未定義)?
hashcode如何縮放到數組索引? 例如,如果哈希碼具有巨大的值,它如何縮放到數組索引,如10,20?
我已經讀過,當達到閾值時,將發生重新散列。 例如,在默認情況下,當16是容量而0.75是負載因子時,則閾值是16*0.75=12
。 一旦添加了12個項目,將發生重新加載並且容量將增加。 這是否意味着table
數組大小增加了?
由於你的帖子有很多問題,我將列舉你的問題作為我答案的一部分。 此外,請注意我將從HashMap
的Java 1.8 b132源代碼中獲取答案。
table
數組(例如put()
方法調用)。 它不會作為地圖實例化的一部分本身發生,除非調用復制構造函數,或者將地圖反序列化為對象。 HashMap
初始化期間定義的容量還是默認容量16(如果在調用構造函數時未定義)? table
數組的長度是基於傳遞給構造函數的初始容量。 如果未指定初始容量且調用默認構造函數,則使用默認容量。 putVal()
方法的實現 。 基本上發生的是代碼采用非常大的哈希值並對表的最后一個元素索引執行bitwise-AND
。 這有效地使鍵/值對的位置與table
數組隨機化。 例如,如果散列值為333(基數為2的101001101)且table
數組大小為32(100000),則最后一個元素索引為31(11111)。 因此,所選擇的指數將是11111 & 101001101 == 01101 == 13
。 threshold
,將調整表的大小。 請注意,通過調整大小,不會修改現有的table
數組。 而是創建一個新table
數組,其容量是第一個table
數組的兩倍。 有關詳細信息,請參閱resize()方法的實現 。 public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
table = new Entry[capacity];
init();
}
上面的代碼塊解釋了填充table
方式和時間。
一旦重新發生,它就不會增加表數組的大小,因為你可以永久地聲明一次數組大小; 它每次都會使用更新的大小創建一個新數組:
void resize(int newCapacity) {
Entry[] oldTable = table;
int oldCapacity = oldTable.length;
if (oldCapacity == MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return;
}
Entry[] newTable = new Entry[newCapacity];
transfer(newTable);
table = newTable;
threshold = (int)(newCapacity * loadFactor);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.