ArrayDeque.allocateElements源码分析

  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  结果还是不变的
          
          
            
          


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值