给定一个数保证输出一定是大于输入值的2的最小幂
- HashMap的tableSizeFor实现了这个函数,下面是细节解析
static final int tableSizeFor(int cap) { //假设传入3和4
//这里-1是为了防止cap已经是2的幂时得到cap*2的结果
int n = cap - 1; //3变2 4变3
//这里2的二进制就是10 | 01 也就变成了二进制的11十进制是3
//同样3的二进制是11 | 01 还是 11
n |= n >>> 1;
//这里2的二进制就是10 | 01 也就变成了二进制的11十进制是3
//同样3的二进制是11 | 01 还是 11
//此时传入的2变成了3,4也变成了3
//后续操作是针对cap较大时的操作,可以省略掉
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1
/*神奇的地方,二进制中位全为1的数再加1就是2的幂*/;
}
应用场景
希望只有一个 i & n就可以实现模运算的场景
例如netty的EventLoop分配
例如HashMap的hash查找分配
更多
(1)思考一下如果我希望hashmap可以一边被我遍历还一边扩容,我该怎么去递增table数组的索引?如果是缩容呢?
(2)HashMap每次扩容都是2的幂那岂不是很浪费?这样做难道仅仅因为为了优化一个取模运算?(引出平摊分析)