基本概念
capacity 即容量,默认16。
loadFactor 负载因子,默认是0.75
threshold 阈值。阈值=容量*负载因子。默认12。当元素数量超过阈值时便会触发扩容。
一般情况下,当元素数量超过阈值时便会触发扩容。每次扩容的容量都是之前容量的2倍。
HashMap的容量是有上限的,必须小于1<<30,即1073741824。
如果容量超出了这个数,则不再增长,且阈值会被设置为Integer.MAX_VALUE( 2^31-1,即永远不会超出阈值了)。
为什么负载因子是0.75?
因为为0.75时HashMap的存储与查询整体效果是最优的
https://baijiahao.baidu.com/s?id=1656137152537394906
源码文档给出的解释
* <p>As a general rule, the default load factor (.75) offers a good
* tradeoff between time and space costs. Higher values decrease the
* space overhead but increase the lookup cost (reflected in most of
* the operations of the {@code HashMap} class, including
* {@code get} and {@code put}). The expected number of entries in
* the map and its load factor should be taken into account when
* setting its initial capacity, so as to minimize the number of
* rehash operations. If the initial capacity is greater than the
* maximum number of entries divided by the load factor, no rehash
* operations will ever occur.
为什么每次扩容的容量是之前的2倍?
源码resize方法
final Node<K,V>[] resize() {
Node<K,V>[] oldTab = table;
int oldCap = (oldTab == null) ? 0 : oldTab.length;
int oldThr = threshold;
int newCap, newThr = 0;
if (oldCap > 0) {
if (oldCap >= MAXIMUM_CAPACITY) {
threshold = Integer.MAX_VALUE;
return oldTab;
}
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
newThr = oldThr << 1; // double threshold
}
...
可以看到newCap=oldCap<<1
即左位移1;为10进制乘以2