×

hashMap为啥初始化容量为2的次幂

96
lucode
2017.11.23 12:01* 字数 270

先看源码部分
hashMap源码获取元素的位置:

static int indexFor(int h, int length) {
    // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
    return h & (length-1);
}

参数解释:
h:为插入元素的hashcode
length:为map的容量大小
&:与操作 比如 1101 & 1011=1001
原因解释:
如果length为2的次幂 则length-1 转化为二进制必定是11111……的形式,在于h的二进制与操作效率会非常的快,而且空间不浪费;
如果length不是2的次幂,比如length为15,则length-1为14,对应的二进制为1110,在于h与操作,最后一位都为0,而0001,0011,0101,1001,1011,0111,1101这几个位置永远都不能存放元素了,空间浪费相当大,更糟的是这种情况中,数组可以使用的位置比数组长度小了很多,这意味着进一步增加了碰撞的几率,减慢了查询的效率!这样就会造成空间的浪费。

附1:与运算(&)计算方式


image.png

附2:

/** 
 * The default initial capacity - MUST be a power of two. 
 */  
static final int DEFAULT_INITIAL_CAPACITY = 16;// 默认初始容量为16,必须为2的幂  
/** 
 * The maximum capacity, used if a higher value is implicitly specified 
 * by either of the constructors with arguments. 
 * MUST be a power of two <= 1<<30. 
 */  
static final int MAXIMUM_CAPACITY = 1 << 30;// 最大容量为2的30次方  
/** 
 * The load factor used when none specified in constructor. 
 */  
static final float DEFAULT_LOAD_FACTOR = 0.75f;// 默认加载因子0.75  
  
/** 
 * The table, resized as necessary. Length MUST Always be a power of two. 
 */  
transient Entry<K,V>[] table;// Entry数组,哈希表,长度必须为2的幂  
/** 
 * The number of key-value mappings contained in this map. 
 */  
transient int size;// 已存元素的个数  
/** 
 * The next size value at which to resize (capacity * load factor). 
 * @serial 
 */  
int threshold;// 下次扩容的临界值,size>=threshold就会扩容  
/** 
 * The load factor for the hash table. 
 * 
 * @serial 
 */  
final float loadFactor;// 加载因子  
java
Web note ad 1