为什么HashMap初始化容量始终是2的指数
1.初始化容量规律
? 最近刷到一个面试题,问HashMap为了保证散列分布,其容量都是2的指数倍,那如果初始化容量为15怎么办?还会是2的指数倍吗?
? 因此去阅读了一下源码,发现传递初始化容量创建HashMap时,会调用另外一个构造方法,如下:
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);
}
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;
}
? 可以通过上面的代码得知,我们传进入的初始化容量并不是直接就会被赋到真正的数组容量当中,而是进行了一系列计算得到最终的初始化容量,可以总结为以下规律:
2.二进制探究初始化容量规律
? 对于以上初始化容量的计算机制,在二进制层面进行剖析:
当传入的初始化容量<2的指数倍时
当传入的初始化容量=2的指数倍时
当传入的初始化容量=2的指数倍+1时
3.总结
? 根据以上信息得知,在给HashMap传入初始化容量N时,底层总是会将N和其右移数的二进制进行或运算,最终总能得出一个全为1的二进制数,然后进行加1,得到2的指数倍的最终容量。
|