gpt4 book ai didi

java - HashMap 容量即使达到阈值也不会增加

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:27:34 25 4
gpt4 key购买 nike

Java doc says - 当哈希表中的条目数超过负载因子和当前容量的乘积时,重新哈希哈希表

在下面的程序中-

HashMap<Integer, String> map = new HashMap<Integer, String>();
int i = 1;
while(i<16) {
map.put(i, new Integer(i).toString());
i++;
}

Key 是 Integer 类型,在插入第 13 到第 15 个元素时,HashMap 容量保持为 16,阈值保持为 12,为什么?

在 map 中添加第 13 个元素后的调试屏幕截图 -

args                 String[0] (id=16)
map HashMap<K,V> (id=19)
entrySet null
hashSeed 0
KeySet null
loadFactor 0.75
modCount 13
size 13
table HashMap$Entry<K,V>[16] (id=25)
threshold 12
values null
i 14

[null, 1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9, 10=10, 11=11, 12=12, 13=13, null, null]

具有字符串类型键的 HashMap - HashMap<String, String>或自定义类 - Map<Employee,Integer>在第 13 次插入时显示预期行为

最佳答案

看起来这种行为是由于在最新版本的 Java 7 中 HashMap PUT 方法的内部实现发生了变化。在浏览了多个版本的源代码之后,找到了我的问题的答案

HashMap put 方法调用 addEntry() 添加新条目 -

public V put(K key, V value) {
...
int hash = hash(key);
int i = indexFor(hash, table.length);
...
addEntry(hash, key, value, i);
...
}

jdk7-b147 HashMap.addEntry方法看起来像 -

addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}

版本 1.7.0_67-b01 的源代码如下所示 -

void addEntry(int hash, K key, V value, int bucketIndex) {
if ((size >= threshold) && (null != table[bucketIndex])) {
resize(2 * table.length);
hash = (null != key) ? hash(key) : 0;
bucketIndex = indexFor(hash, table.length);
}
createEntry(hash, key, value, bucketIndex);
}

因此,在最近的 Java 版本中,HashMap 可能不会单独根据阈值调整大小。如果 bucket 为空条目仍然会进入而不调整 HashMap 的大小

Java 8 可能有不同的行为,source code of version 8-b132显示 PUT 已完全重新实现 -

put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}

putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
....
}

final Node<K,V>[] resize() {
//many levels of checks before resizing
}

Java 文档可能不会像 Java 版本那样频繁更新!谢谢斯蒂芬

关于java - HashMap 容量即使达到阈值也不会增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26924628/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com