HashMap钦定初叶容积,在分裂版本JDK的计算【财神

2019-11-27 02:12栏目:摄影资讯

配置参数

  • 特色:缔杰(DIGIPOD) C2530N BH-52N 铝合金 专业三脚架(黑色)(承重 8KG)

查看完整参数>>

 

  

也就是说,指定数组容量大于 2的6次方(64)后,JDK1.8的效率更高

public HashMap(int initialCapacity, float loadFactor) 

最终能保证所有低位上都是1: 1xxxxxxxx -> 111111111 。  1 变为 1000000000 ,是大于等于该数的最小2的N次方

2.1 参数不是2的N次方,转为二进制

如果一个数n,其不为1,且n-1 & n = 0,那么n就是一个2的整数次幂

1、在JDK低版本中,通过循环移位运算,保证了初始容量为2的N次方

4、传参恰好为2的N次方时的优化

 

右移或运算,截止到16,能保证最多32位上都是1,是因为int型的最大值231-1,是31位

HashMap的指定初始容量的构造函数:

初始容量是根据参数 initialCapacity,求出 大于等于 initialCapacity 的最小的 2的N次方。

3、比较

 

2、JDK1.8中,对该运算进行了优化

第二步 n |= n >>> 1;   1xxxxxxxx 右移一位 变成 1xxxxxxx, 或运算后变为 11xxxxxxx ,不管低位

低版本中,假设传参为2的N次方,比较 位移,一共计算了 2 * N 次

JDK1.8里加这个判断可以减少计算

public HashMap(int initialCapacity, float loadFactor) {  
    ......

    int capacity = 1;  
    while (capacity < initialCapacity)  
        capacity <<= 1;  

    ...... 
}

...... 

static final int tableSizeFor(int cap) {
    int n = cap - 1;

    if(cap & n == 0) // 传参为2的N次方
        return (cap >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : cap;

    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的N次方

第一步 1xxxxxxxx - 1,由于低位至少有一个1,所以减1后,位数不变

第四步 n |= n >>> 4;   1111xxxxx 右移四位 变成 1111x, 或运算后变为 11111111x ,不管低位

1xxxxxxxx (假设9位,x中至少有一个为1),大于等于该数的最小2的N次方如下,十位

public HashMap(int initialCapacity, float 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;
}

1000000000

举例 1000, n-1后变为 111,右移或运算后还是 111, 1后变为 1000

 

 

第三步 n |= n >>> 2;   11xxxxxxx 右移两位 变成 11xxxxx, 或运算后变为 1111xxxxx ,不管低位 

容量是2的N次方的原因,可参见 

JDK1.8中,减法 位移 或运算,大概计算 11 次

版权声明:本文由财神彩票网站发布于摄影资讯,转载请注明出处:HashMap钦定初叶容积,在分裂版本JDK的计算【财神