当执行new HashMap<>(10)时都执行了什么?
首先是虚拟机规范有规定,当使用new语句新建对象时会触发类的初始化操作,但那是对于未初始化的类.实际会先去常量池中定位到HashMap类的符号引用,并检查这个类是否已经被加载解析初始化过.没有的话先进行类加载过程.然后为对象分配内存.但是我们从执行构造器开始:
new HashMap<>(10)使用的是一个int参数的构造器:
public HashMap(int initialCapacity) {
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
可以看到构造器中只定义了容量和装填因子大小,和一个threshold,这个threshold是什么,我们来看一下:
/**
* The next size value at which to resize (capacity * load factor).
int threshold;
官方的注释中解释是下一次执行resize()的阈值,也就是容量大于它时要进行resize扩容操作.但是有一种特殊情况,就是在第一次执行resize操作的时候,threshold是建立数组的大小.下面会有介绍到.
下面我们看到threshold是用这句this.threshold = tableSizeFor(initialCapacity);来给初始值的. 那tableSizeFor做了什么:
/**
* Returns a power of two size for the given target capacity.
*/
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
直接看可能有点蒙,看官方给出的解释,也就是顶上的注释行: 返回一个比给定值大的最小的二的次幂. 我们这里传进来的是10,那么最后return 的是什么:
n-1后变成 9
n |= n >>> 1后n=13
n |= n >>> 2后n=15
n |= n >>> 4后n=15
n |= n >>

本文详细介绍了执行`new HashMap<>(10)`时的内部过程,包括类加载、内存分配、构造器执行以及HashMap中数组的创建。在构造器中,设置了容量和装填因子,但并未创建Node数组。数组的实际创建发生在第一次`put()`操作时,通过`resize()`函数完成,该函数会根据传入容量调整为最小的二的次幂并初始化Node数组。
最低0.47元/天 解锁文章
955

被折叠的 条评论
为什么被折叠?



