问题引入
注:本文代码源自java 9
。
- 阿里的插件对于初始化HashMap时,调用无参构造方法,提示如下:
- 那么问题来了,如果已知需要向 map 中 put n次,那么需要设定初始容量为多少?
- 单纯的我今天上午还认为是合理的容量是 n + 1 即可,直到看了源码;
- 应注意,
map.size
获取的是当前map中键值对的个数,而不是容量。
当初始化的时候,没有指定容量,情况如何?
1.直接调用如下构造函数(无参)
/**
* Constructs an empty {@code HashMap} with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
- 首先应该清楚,loadFactor 是 装载因子(通俗来讲,若值为0.5f,那么当map元素达到 容量*0.5f的时候,就应该做扩容等操作)
- HashMap对象实际上只有 threshold(临界值,阈值) 属性,每次put()后,需要比较的是阈值与size(map中已有键值对的个数)
- 至于容量属性,实际上各个方法中用的是
transient Node<K,V>[] table;
中 table 的长度 - 其次,作为一个没有被赋值的全局变量,在类的构造函数中必须要赋值。
- 本构造方法上说明:构造了一个空的HashMap,默认容量为16,装载因子为0.75。
- 然而可以清楚地看到,此构造方法只是将常量
DEFAULT_LOAD_FACTOR
赋值给装载因子,但没有设定容量。 - 当调用
put()
时,如下方式设定了初始容量。 - 调用
putVal(hash(key), key, value, false, true)
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
- 在putVal()中,进入第一个if,调用resize()
final V 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;
//省略无关代码
}
- 在下方代码中,oldCap 与 oldThr 初始都为0,故直接进入else{}
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)
//省略无关代码
else if (oldThr > 0) // initial capacity was placed in threshold
//省略无关代码
else { // zero initial threshold signifies using defaults
newCap = DEFAULT_INITIAL_CAPACITY;//设定 newCap = 16
newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);//设定 newThr = 16 * 0.75 = 12
}
threshold = newThr;//将对象的 threshold(临界值,阈值) 属性设置为 newThr
Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = //将对象的 table 属性设置为刚实例化的 newTab
//省略无关代码
return newTab;//并返回
- 综上,默认无参的构造方法设定初始容量为16,装载因子为0.75f。
当我们指定容量为n的时候,情况如何?
参考文章:http://blog.csdn.net/fan2012huan/article/details/51087722
原文地址:https://www.cnblogs.com/kangkaii/p/8471619.html
时间: 2024-11-05 20:41:35