ArrayList源码分析

ArrayList底层是数组实现的,可以做到动态增长。下面通过简单的源码分析来大致看看ArrayList的添加过程。

新建一个list 并对add()方法打上断点,debug。

add()方法如下,size一开始并未赋值  为0

/**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

进入到ensureCapacityInternal()方法  此时minCapacity为1  elementData刚开始为  transient Object[] elementData的空数组

private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

再进入calculateCapacity()方法,此时 DEFAULTCAPACITY_EMPTY_ELEMENTDATA也是一个空数组,

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

而  DEFAULT_CAPACITY一开始默认为10

由此可见,第一次添加的时候执行 if里面的方法  返回默认长度和minCapacity的最大值也就是10;以后进入由于elementData不为空  因此直接返回minCapacity

private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
1 private void ensureExplicitCapacity(int minCapacity) {
2         modCount++;
3 
4         // overflow-conscious code
5         if (minCapacity - elementData.length > 0)
6             grow(minCapacity);
7     }

5行此时 minCapacity为默认的10 明显大于一开始的空数组的长度  进入grow();方法  ;同时,该方法也说明只有当minCapacity大于elementData数组长度的时候开始进行扩容。

 1 private void grow(int minCapacity) {
 2         // overflow-conscious code
 3         int oldCapacity = elementData.length;
 4         int newCapacity = oldCapacity + (oldCapacity >> 1);
 5         if (newCapacity - minCapacity < 0)
 6             newCapacity = minCapacity;
 7         if (newCapacity - MAX_ARRAY_SIZE > 0)
 8             newCapacity = hugeCapacity(minCapacity);
 9         // minCapacity is usually close to size, so this is a win:
10         elementData = Arrays.copyOf(elementData, newCapacity);
11     }

第四行新的数组长度为  原数组长度加上原数组长度除以二  此时还是为0,第五行此时新容量小于minCapacity因此新容量就为minCapacity10、

然后进去第十行对数组进行复制,也就创建了一个长度为10的数组。

 一路返回至add()方法  添加元素  size++

做个总结,ArrayList默认的数组为0,当第一次添加元素的时候便开始扩容为默认值10。随后如果有数组不断地添加,只有在size大于原数组长度的时候,开始扩容。扩容方法为原长度除以二再加原长度,也就是1.5倍扩容。

由于水平有限,有错误欢迎指出,一起学习。

原文地址:https://www.cnblogs.com/helloDuo/p/9418554.html