码迷,mamicode.com
首页 > 其他好文 > 详细

HashMap指定初始容量,在不同版本JDK的计算

时间:2016-10-21 19:36:24      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:htm   大于等于   运算   最大   www   位运算   class   actor   ble   

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

public HashMap(int initialCapacity, float loadFactor) 

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

容量是2的N次方的原因,可参见 http://www.cnblogs.com/xwdreamer/archive/2012/06/03/2532832.html

 

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

public HashMap(int initialCapacity, float loadFactor) {  
    ......
    
    int capacity = 1;  
    while (capacity < initialCapacity)  
        capacity <<= 1;  
  
    ...... 
}

 

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

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;
}

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

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

1000000000

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

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

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

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

...... 

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

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

2.2 参数是2的N次方

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

 

3、比较

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

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

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

 

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

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

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

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;
}

  

 

HashMap指定初始容量,在不同版本JDK的计算

标签:htm   大于等于   运算   最大   www   位运算   class   actor   ble   

原文地址:http://www.cnblogs.com/yjiang/p/5985480.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!