Java集合框架之ArrayList源码分析及如何扩展容量

ArrayList底层维护的是一个动态数组,每个ArrayList实例都有一个容量,并随着往ArrayList里面添加元素,其容量也自动增长。
下面通过ArrayList源码分析其原理。

以下代码取自JDK1.8

2.代码分析

注:请阅读代码注释结合代码来看

1.主要变量

transient Object[] elementData; // 真正存储数据的数组,整个ArrayList的元素数据都存在这个Object[]中. private int size; // 实际ArrayList存储数据的元素大小(非容量).


2.构造函数

//指定ArrayList的大小 public ArrayList(int initialCapacity) { if (initialCapacity > 0) { // 指定数组大小(上面说了ArrayList是以elementData 存储元素数据的) this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { // 指定一个空数组,没有任何大小(相当于只是声明了数组变量) // private static final Object[] EMPTY_ELEMENTDATA = {}; this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } public ArrayList() { // 指定一个空数组,没有任何大小(相当于只是声明了数组变量) // private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //传入一个集合 public ArrayList(Collection<? extends E> c) { // 返回包含此 collection 中所有元素的数组 elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) // 复制指定的数组,返回包含相同元素和长度的Object类型的数组 elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // 指定一个空数组,没有任何大小(相当于只是声明了数组变量) // private static final Object[] EMPTY_ELEMENTDATA = {}; this.elementData = EMPTY_ELEMENTDATA; } }

1) ArrayList()
    构造一个没有指定大小的空列表(相当于只是声明了数组变量)。

2) ArrayList(int initialCapacity)
    initialCapacity不为 0 时构造一个具有指定初始容量的空列表。
    如果initialCapacity指定为 0 ,那么还是同ArrayList()一样。

3) ArrayList(Collection c)
    (注:因此处代码放入会影响显示,只需知道是最后一个传入Collection的方法即可,见上面的代码块最后一个方法)
    构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。

3.add方法

public boolean add(E e) { ensureCapacityInternal(size + 1); //添加元素数据,为所存在的最大元素+1位置增加元素 elementData[size++] = e; return true; }

解说:上面代码块 add 方法调用ensureCapacityInternal(size + 1);    如下代码:

private void ensureCapacityInternal(int minCapacity) { // 如果数组是为空数组,那么设置当前数组默认容量 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //默认容量为:private static final int DEFAULT_CAPACITY = 10; minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); }

解说:上面代码块 ensureCapacityInternal 方法拿到了默认值为10的默认数组空间
           然后调用ensureExplicitCapacity(minCapacity);    如下代码:

private void ensureExplicitCapacity(int minCapacity) { modCount++; //假如是刚刚创建List<String> list1 = new ArrayList<String>(); // 当前容量10 - 所存元素大小0 if (minCapacity - elementData.length > 0) grow(minCapacity); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/475e6e2060e0e671f2a09d481aef973a.html