源码学习---ArrayList的扩容源码分析

ArrayList的扩容源码分析

源码如下:

//下面是ArrayList的扩容机制
//ArrayList的扩容机制提高了性能,如果每次只扩充一个,
//那么频繁的插入会导致频繁的拷贝,降低性能,而ArrayList的扩容机制避免了这种情况。
 /**
  * 如有必要,增加此ArrayList实例的容量,以确保它至少能容纳元素的数量
  * @param   minCapacity   所需的最小容量
  */
 public void ensureCapacity(int minCapacity) {
     int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
         // any size if not default element table
         ? 0
         // larger than default for default empty table. It's already
         // supposed to be at default size.
         : DEFAULT_CAPACITY;

     if (minCapacity > minExpand) {
         ensureExplicitCapacity(minCapacity);
     }
 }
//得到最小扩容量
 private void ensureCapacityInternal(int minCapacity) {
     if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
           // 获取默认的容量和传入参数的较大值
         minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
     }

     ensureExplicitCapacity(minCapacity);
 }
//判断是否需要扩容,上面两个方法都要调用
 private void ensureExplicitCapacity(int minCapacity) {
     modCount++;

     // 如果说minCapacity也就是所需的最小容量大于保存ArrayList数据的数组的长度的话,就需要调用grow(minCapacity)方法扩容。
     //这个minCapacity到底为多少呢?举个例子在添加元素(add)方法中这个minCapacity的大小就为现在数组的长度加1
     if (minCapacity - elementData.length > 0)
         //调用grow方法进行扩容,调用此方法代表已经开始扩容了
         grow(minCapacity);
 }

核心方法grow分析

     /**
     * ArrayList扩容的核心方法。
     */
    private void grow(int minCapacity) {
       //elementData为保存ArrayList数据的数组
       ///elementData.length求数组长度elementData.size是求数组中的元素个数
        // oldCapacity为旧容量,newCapacity为新容量
        int oldCapacity = elementData.length;
        //将oldCapacity 右移一位,其效果相当于oldCapacity /2,
        //我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍,
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量,
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //再检查新容量是否超出了ArrayList所定义的最大容量,
        //若超出了,则调用hugeCapacity()来比较minCapacity和 MAX_ARRAY_SIZE,
        //如果minCapacity大于MAX_ARRAY_SIZE,则新容量则为Interger.MAX_VALUE,否则,新容量大小则为 MAX_ARRAY_SIZE。
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

 源码中对于容量的计算采用的为位移机制,这样使用的原因是因为对于大数据的2进制运算,位移运算符比那些普通运算符的运算要快的很多。提高性能

猜你喜欢

转载自blog.csdn.net/qq_35248832/article/details/107366615