private void allocateElements(int numElements) {
int initialCapacity = MIN_INITIAL_CAPACITY;
// Find the best power of two to hold elements.
// Tests "<=" because arrays aren't kept full.
if (numElements >= initialCapacity) {
initialCapacity = numElements;
initialCapacity |= (initialCapacity >>> 1);
initialCapacity |= (initialCapacity >>> 2);
initialCapacity |= (initialCapacity >>> 4);
initialCapacity |= (initialCapacity >>> 8);
initialCapacity |= (initialCapacity >>> 16);
initialCapacity++;
if (initialCapacity < 0) // Too many elements, must back off
initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
}
elements = new Object[initialCapacity];
}
上面的代码,我看了几个鈡,终于有点理解了,也不知对,还是错,这段代码主要是获取initialCapacity 最近的2的幂次方,下面是我分析的结果,有点长,我也不知怎么简化
initialCapacity |= (initialCapacity >>> 1);
initialCapacity |= (initialCapacity >>> 2);
initialCapacity |= (initialCapacity >>> 4);
initialCapacity |= (initialCapacity >>> 8);
initialCapacity |= (initialCapacity >>> 16);
假设我的initialCapacity = 32
我们先来看第一个 initialCapacity |= (initialCapacity >>> 1);
32的二进制是:00000000000000000000000000100000
initialCapacity >>> 1 也就是无符号右移1位,也就是等于16,
16的二进制:00000000000000000000000000010000
initialCapacity = initialCapacity | (initialCapacity >>> 1) 也就是 32 | 16
00000000000000000000000000100000 =====》32
或(|)
00000000000000000000000000010000 =====》16
00000000000000000000000000110000 =====》48
仔细观察,你会发现最后的结果110000(48) 比 原来的数据100000(32)第二位的0变成了1
我们继续 initialCapacity |= (initialCapacity >>> 2);
这时 initialCapacity = 48
48的二进制: 00000000000000000000000000110000
initialCapacity >>> 2 也就是 48 无符号右移2位 也就是等于12
12的二进制:00000000000000000000000000111100
00000000000000000000000000110000 =====》48
或(|)
00000000000000000000000000001100 =====》12
00000000000000000000000000111100 =====》60
仔细观察,你会发现最后的结果111100(60) 比 原来的数据100000(110000)第三位,第四位的0都变成了1
我们继续 initialCapacity |= (initialCapacity >>> 4);
这时 initialCapacity = 60
initialCapacity >>> 4 也就是 60无符号右移2位 也就是等于3
12的二进制:00000000000000000000000000000011
00000000000000000000000000111100 =====》48
或(|)
00000000000000000000000000000011 =====》3
00000000000000000000000000111111 =====》63
仔细观察,你会发现最后的结果111111(63) 比 原来的数据111100(110000)第五位,第六位的0都变成了1
经过这三步,我发现,这代码就是为了把100000(32)的不是1的位弄成1的位
那这是为什么呢?
你看看 1, 4 ,8 ,16,32,64的二进制就完事了
64 = 1000000
比喻上面的63 (111111) + (000001) = 1000000
所以上面的代码是为了找出 2的幂次方-1的数,也就是说32的最近2的幂次方不就是64吗????
至于 为啥是 >>> 1 >>>2 >>>4 >>>8 >>>16 ?
>>> 1 : 这个时候110000(48) 比 原来的数据100000(32)第二位的0变成了1,那我们就可以确定2位,第1位,第二位肯定是1了,下面我直接>>>2 就好
>>> 2 这个时候111100(60) 比 原来的数据100000(110000)第三位,第四位的0都变成了1,那我们可以确定第1,2,3,4,肯定是1了,所以下面我直接>>>4就好
>>>4 这个时候 111111(63) 比 原来的数据111100(110000)第五位,第六位的0都变成了1,那我们可以确定 第1,2,3,4,5,6,都是1了,尽管下面>>>8,>>>16,最后的结果还是111111(63),因为
00000000000000000000000000111111 =====》63 >>>8 右移8位
或(|)
00000000000000000000000000000000 =====》0
00000000000000000000000000111111 =====》63 结果还是不变的
本文详细解析了一段用于计算数组最优容量的代码,通过位操作实现寻找最接近指定数值的2的幂次方,确保内存高效利用。
462

被折叠的 条评论
为什么被折叠?



