先上源码:
static final int tableSizeFor(int i) {//i为自定义容器的大小
int j = i - 1;
j |= j >>> 1;
j |= j >>> 2;
j |= j >>> 4;
j |= j >>> 8;
j |= j >>> 16;
return j >= 0 ? j < MAXIMUM_CAPACITY? j + 1 : MAXIMUM_CAPACITY: 1;
}
这段代码的作用是将一个非负整数(自定义大小)转换成第一个大于等于它本身的 2 的幂次方的数。
例如,设置大小为 9,则经过计算得到 16。
基本思路:二进制下低位全部转换成 1,再加一,大小为 9 的时候,00001001,要得到 00001111,再加一得到 00010000,即 16。
具体计算过程如下:
第一步:j |= j >>> 1;
00001000 >>> 1 ==> 00000100
00001000 | 00000100 ==> 00001100
第二步:j |= j >>> 2;
00001100 >>> 2 ==> 00000011
00001100 | 00000011 ==> 00001111
第三步、第四步同样。
原理:
利用非负整数第一位二进制为 1 的特点,结合左移和或运算,将原数据低位转换成 1。
细节:
- 算法开头需要将原始大小减一,目的是考虑原始大小为 2 的幂次方时,得到结果还是其本身。
- 返回值:必须为非负整数,否则返回 1,若超过最大值,则返回最大值(int 能存储的最大值)
- 为什么左移 16 位就计算结束了?因为
int
类型数据占 32 位,前 4 步将高 16 位转换成 1,最后一步将低 16 位转换成 1。