ArrayList学习笔记
- ArrayList本质上是对数组 elementData 的维护
transient Object[] elementData; // non-private to simplify nested class access
- EMPTY_ELEMENTDATA 与 DEFAULTCAPACITY_EMPTY_ELEMENTDATA本质上都是空的Object类型数组。其中DEFAULTCAPACITY_EMPTY_ELEMENTDATA用于无参构造函数,在添加元素时,会默认将数组长度置为DEFAULT_CAPACITY(10)。而EMPTY_ELEMENTDATA用于有参构造函数中指定容量为0的情况,不会初始化数组默认长度。
//无参构造函数 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } //有参构造函数 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 int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; }
- 如果添加元素时,需要扩容,默认将容量扩充为原来的1.5倍。数组扩充使用Arrays.copyOf 方法。
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); }
- 删除元素后需要将被删除元素之后的元素向前移动,使用了System.arraycopy方法来移动数组。该方法为native方法,高效快捷。
public E remove(int index) { 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; } //native方法 public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
-
参考链接:
- 关于ArrayList的学习