对HashMap中容量计算算法的不了解

时间:2018-10-19 13:03:03

标签: java algorithm data-structures bitwise-operators

我有兴趣了解HashMap中容量计算算法的工作。

如果我们创建具有某些所需容量20的Object HashMap,则该算法将始终计算下一个最高容量,即(2 ^ x> 20)

下面是jdk的实现.....

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进行除法,然后按位“或”取较旧的值。 之所以这样做,是因为他们必须分配下一个大于n的(2 ^ x)值,

但是有人可以在每个步骤中帮助我解释一些数字会发生什么,我试图调试但感到复杂。

我想像下面的一些实现。

private static int calculateCapacity(int cap){

    int max_capcity = 256;
    if(cap<16){
        return 16;
    }else if(cap <32){
        return 32;
    }else if(cap <64){
        return 64;
    }else if(cap < 128){
        return 128;
    }
    return max_capcity;
}

上面的实现可以代替复杂的按位和右移使用什么。

1 个答案:

答案 0 :(得分:2)

此算法是一种确定2的最小幂的快速方法,该最小幂大于或等于给定的cap

它的工作方式是计算仅设置一位的数字,并且该位比原始数字中所有其他位的位置高(如果只​​有两位,则位于原始数字的最高位)一位)。为此,它将所有小于前导位的位设置为1,然后添加1

这是它对正数工作的方式,写为001XXXXXXXXX(前导位后面的位无关紧要):

int n = cap - 1;    // will not change anything to the leading bit except
                    // if cap is already a power of 2. In that case,  
                    // we had cap = 001000000000 and now n = 000111111111 and
                    // the other lines won't change anything, we just have to
                    // do +1 in the end and we're done, n = cap;
                    // otherwise, let's assume that not every 'X' is a '0'

n |= n >>> 1;       // n >>> 1 = 0001XXXXXXX
                    // so    n = 0011XXXXXXX

n |= n >>> 2;       // n >>> 2 = 000011XXXXX
                    // so    n = 001111XXXXX

n |= n >>> 4;       //       n = 0011111111X

n |= n >>> 8;       //       n = 00111111111

n |= n >>> 16;      //       n = 00111111111

return n + 1;       //  result = 01000000000

对于负数,n在每一行均为负,因为符号位始终为1,因此结果将为1