之前写过一篇关于集合的初始化容量的问题,当时提到我看过的ArrayList一共有两版初始化,但是由于当时没有另一版的jdk,于是只有在今天补出。
第一篇地址:http://blog.csdn.net/silk_bar/article/details/37915285
下面开始,首先看本类定义的变量:
private static final int DEFAULT_CAPACITY = 10; private static final Object[] EMPTY_ELEMENTDATA = {}; private transient Object[] elementData;
接下来看构造器:
public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { super(); this.elementData = EMPTY_ELEMENTDATA; }
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { protected AbstractList() { } }
public boolean add(E e) { ensureCapacityInternal(size + 1); //首次执行时size==0 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { if (elementData == EMPTY_ELEMENTDATA) { //默认初始化时符合此条件(具体看此文章上面) minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//用默认常量(10)和入参比较,返回大的即默认常量10 } ensureExplicitCapacity(minCapacity); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0)//10 - 0 > 0符合,进入grow方法 grow(minCapacity); } private void grow(int minCapacity) {//此时入参minCapacity为10 // overflow-conscious code int oldCapacity = elementData.length; //oldCapacity为0 int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容1.5倍,详细见上篇文章 if (newCapacity - minCapacity < 0)//扩容后仍小于入参,则新长度为入参(即为默认长度10) newCapacity = minCapacity; 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);//扩容为新长度,即我们上面的常量10 }同样,代码已经写的很清楚了,在首次add元素时,会将数组容量扩充为10.
这版与上版的差别在于这版初始化时只是赋值了一个空的数组,而上班直接指定了长度为10的一个数组。这其实就是一种典型的懒汉式设计,这样的好处在于初始化速度会很快,而且节约空间,等到真正使用时才会进行扩容处理。
以上均为各人见解,若有异议,欢迎提出,共同讨论。