(1)List<String> list = new ArrayList<>(); public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
第一个结论:ArrayList底层是数组数组
第二个结论:若用无参构造器的方式实例化ArrayList,只是声明了数组,还未分配空间安全
(2)List<String> list = new ArrayList<>(10); public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } private static final Object[] EMPTY_ELEMENTDATA = {};
补充第二结论:若用有参构造器的方式实例化ArrayList且initialCapacity大于0,则既声明了数组,也分配了空间多线程
public boolean add(E e) { //校验数组容量,若空间不够则扩容复制生成一个新的数组 ensureCapacityInternal(size + 1); //赋值 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } /** * 若数组是经过无参构造器的方式实例化的话,返回的minCapacity为10,最后会经过grow方法复制生成一个大小为10的数组 * 若数组是经过有参构造器的方式实例化的话,返回的minCapacity为当前要操做的数组下标,不建议声明小于10的数组空间,由于这样前几回add都要去扩容复制生成一个新的数组 */ private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } //扩容大小:原数组大小 + 原数组大小/2 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) 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); }
其它说明并发
public E remove(int index) { //检查index是否 >= size,若大于则报数组越界异常 rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
其它说明this
public static void arraycopy( Object src, //源数组 int srcPos, //源数组要复制的起始位置 Object dest, //目标数组 int destPos, //目的数组放置的起始位置 int length //复制长度 )