我有兴趣了解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;
}
上面的实现可以代替复杂的按位和右移使用什么。
答案 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
。