默认初始容量为10,底层用的是对象数组实现的。
public void ensureCapacity(int minCapacity)。确保数组最小容量,用于添加元素的时候。
它的父类AbstractList只有一个抽象方法abstract public E get(int index);
modCount:记录list结构被改变的次数,其实是改变大小时会自增,主要是add和remove,set并不会使modCount自增。
会影响modCount的操作:add,remove、ensureCapacityInternal、fastRemove、clear、trimToSize、removeRange(是那些会改变容量的操作)。
还有个listIterator()方法,返回一个迭代器。
扩容的时候的代码:
public void ensureCapacity(int minCapacity) { if (minCapacity > 0) ensureCapacityInternal(minCapacity); } private void ensureCapacityInternal(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length;
//变成原来容量的1.5倍 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); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
再看一个方法:
public void trimToSize() { modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { elementData = Arrays.copyOf(elementData, size); } }
elementData的长度会被拓展,size标记的是其中包含的元素的个数。所以会出现size很小但elementData.length很大的情况,将出现空间的浪费。trimToSize将返回一个新的数组给elementData,元素内容保持不变,length跟size相同,节省空间
private void fastRemove(int index):不进行边界检查,不返回删除的值。
clear方法:并没有修改elementData的长度,只是将所有元素置为null,size设置为0。
subList会调用父类(ArrayList)的removeRange方法。