虽然有点晚了,但这可能会帮助其他用户寻找这个问题的答案。
关于你的第一个问题,哈希图中会有多少个桶?--
如果您在实例化 HashMap 时未在构造函数参数中指定,则默认容量为 16 个桶。
现在我们来看第二个问题,即hash map 是否按需创建一个新的bucket(即当hash code 与任何现有bucket 的hash code 值都不匹配时)?
看看Hashmap的put方法here的实现会很有趣。
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K, V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
如果你仔细观察,接受 key 的 hashmap 作为参数的方法 hash 在 put 方法中被调用。这种方法的作用是防止质量差的散列函数。使用此 indexFor 方法后,标识将插入元素的索引(桶)。此方法返回的索引始终指向现有存储桶。因此,不会出现密钥的哈希码指向不存在的存储桶的情况。
那么hashmap什么时候创建一个新的bucket呢?它在javase docs 中得到了巧妙的解释。
它说:“HashMap的一个实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的桶数,初始容量只是哈希时的容量表被创建。负载因子是哈希表在其容量自动增加之前被允许达到多满的量度。当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表表被重新散列(即内部数据结构被重建),使得散列表的桶数大约是两倍。”
希望对您有所帮助。