1、为什么hashmap的数组初始化大小都是2的次方大小时,hashmap的效率最高?
/** * The default initial capacity - MUST be a power of two. */ static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
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; if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); ... 代码省略 }
执行put操作时,先通过i = (n - 1) & hash获取插入数组的坐标,n即上面的DEFAULT_INITIAL_CAPACITY,该属性的注释指出必须时2的次方大小,歪?
en
1.1、首先了解以下&运算
运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即:两位同时为“1”,结果才为“1”,否则为0
1.2、如果DEFAULT_INITIAL_CAPACITY不为2的次方?
假如DEFAULT_INITIAL_CAPACITY为15,那么(n - 1) & hash 就变成了 14 & hash 即 01110 & hash,因为01110的尾数为0,那么01110 & hash 不可能出现尾数为1的情况,导致table上尾数为1的位置不能存放元素,空间浪费大,使用的位置比数组长度小很多,导致碰撞的几率增大,所以hashmap的初始化大小都是2的次方。