1. capacity为什么要求是2的幂次方
下来看JDK8中的属性DEFAULT_INITIAL_CAPACITY,如下所示:
List-1
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
当进行put时,使用哪个bucket,计算方式如下:
List-2
int index=(table.length-1)&hash
由于table.length的值总是2的幂次方,所以table.length-1的值,转换为二进制后最右边的几位都是1。比如table.length的值是16,那么table.length-1的二进制是1111。所以做&运算时,值是多少很大程度上取决于hash的值,这样做是为了减少hash碰撞,争取将entry均匀的分散在bucket中。
2.HashMap的扩容
看JDK8中HashMap的源码片段,如下:
List-3
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这条语句,oldCap=oldTable.length,所以扩容时capacity是翻倍。