【发布时间】:2019-11-22 05:12:52
【问题描述】:
我知道 HashMap 在内部是如何工作的。但是,在使用 TreeNode 实现检查 HashMap 代码时,我没有得到增加存储桶大小的目标,但在存储桶大小达到 MIN_TREEIFY_CAPACITY = 64 之前,我没有得到 treeify。
注意:我考虑过Map m = new HashMap();,所以默认大小为16。
默认值。
static final int TREEIFY_THRESHOLD = 8;
static final int MIN_TREEIFY_CAPACITY = 64;
HashMap#putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)
我从putVal 方法中提取了几行代码。
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
所以每当 binCount 达到 7 时,它就会调用 treeifyBin(tab, hash); 现在让我们按照方法 treeifyBin 中的代码进行操作。
HashMap#treeifyBin(Node[] tab, int hash)
final void treeifyBin(Node<K,V>[] tab, int hash) {
int n, index; Node<K,V> e;
if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
resize();
else if ((e = tab[index = (n - 1) & hash]) != null) {
TreeNode<K,V> hd = null, tl = null;
....
}
}
为什么?
在此方法中,首先在IF 中检查当前tab 的大小是否小于MIN_TREEIFY_CAPACITY = 64,然后调用resize()。它在内部将tab 的大小从默认的16 增加到32,并将所有元素转移到新的tab。再次 32 到 64。我认为这是开销或不必要的。
那么这背后的目标是什么?在putVal 中使用TREEIFY_THRESHOLD 检查大小,但在到达MIN_TREEIFY_CAPACITY 之前不执行treeify。
【问题讨论】: