属性
静态属性
private static final int DEFAULT_CAPACITY = 10; //默认初始容量
private static final Object[] EMPTY_ELEMENTDATA = {}; //空数组,指定初始容量是0时返回
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认数组
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //数组容量最大值,int的最大值减八
普通属性
transient Object[] elementData; //数组数据
private int size; //数组大小
protected transient int modCount = 0; //继承AbstractList的属性
构造函数
默认无参构造函数,数据默认为DEFAULTCAPACITY_EMPTY_ELEMENTDATA
public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
带初始容量的构造函数,如果初始容量为0则使用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); } }
传入集合的构造函数,这里如果直接传入null会报空指针异常,如果集合大小为0则使用EMPTY_ELEMENTDATA,否则构建对应数组大小的数组,并把size设置为对应大小
public ArrayList(Collection<? extends E> c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { elementData = a; } else { elementData = Arrays.copyOf(a, size, Object[].class); } } else { // replace with empty array. elementData = EMPTY_ELEMENTDATA; } }
常用方法
size 数组大小,直接返回size值
public int size() { return size; }
add 添加元素
先通过ensureCapacityInternal方法来确保容量,然后把添加的元素放在存储数据的数组的size位置,最后size自增,返回布尔值true。
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
确保容量的方法如下:入参为添加完元素后的数组大小size,此大小为数组容量的最小值minCapacity,然后通过calculateCapacity方法计算出最小容量,如果数组是通过无参构造器构造的,那么最小容量为DEFAULT_CAPACITY(10)和传入数组大小size两个数值中较大的那个。否则最小容量就是传入的size大小。
然后再调用ensureExplicitCapacity,如果此时的最小容量已经大于了当前数组的容量,那么就需要调用grow方法来扩充数组数组容量
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private static int calculateCapacity(Object[] elementData, int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
grow扩充方法的逻辑如下:参数为数组容量最小值
扩充默认按照原大小的二分之一扩充,如果扩充后的大下还是不满足最小容量或者超出了int最大值变为了负数就直接将最小容量作为新的数组大小,如果扩充后的大小大于数组容量大小的最大值则返回hugeCapacity,如果最小容量由于大于int最大值变为复数则抛出OOM异常,如果大于MAX_ARRAY_SIZE则返回int的最大值,否则返回MAX_ARRAY_SIZE。
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); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
addAll添加一个集合到数组中,这里传入null同样会空指针。
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0; }
和上面的方法基本一致,多了一个校验插入位置的判断,如果位置不对报IndexOutOfBoundsException异常
public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); Object[] a = c.toArray(); int numNew = a.length; ensureCapacityInternal(size + numNew); // Increments modCount int numMoved = size - index; if (numMoved > 0) System.arraycopy(elementData, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; }
isEmpty 判断数组是否为空,直接返回size是否为0 public boolean isEmpty() { return size == 0; }
contains 判断数组中是否存在此元素
public boolean contains(Object o) { return indexOf(o) >= 0; } indexOf元素在数组中的位置,没有找到返回-1 public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
remove 移除指定元素
public boolean remove(Object o) { if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); return true; } } return false; } private void fastRemove(int index) { modCount++; 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 }
remove 移除指定下标元素
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; }
removeRange移除一段元素
protected void removeRange(int fromIndex, int toIndex) { modCount++; int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved); // clear to let GC do its work int newSize = size - (toIndex-fromIndex); for (int i = newSize; i < size; i++) { elementData[i] = null; } size = newSize; }
removeall 删除集合中的元素
public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, false); } private boolean batchRemove(Collection<?> c, boolean complement) { final Object[] elementData = this.elementData; int r = 0, w = 0; boolean modified = false; try { for (; r < size; r++) if (c.contains(elementData[r]) == complement) elementData[w++] = elementData[r]; } finally { // Preserve behavioral compatibility with AbstractCollection, // even if c.contains() throws. if (r != size) { System.arraycopy(elementData, r, elementData, w, size - r); w += size - r; } if (w != size) { // clear to let GC do its work for (int i = w; i < size; i++) elementData[i] = null; modCount += size - w; size = w; modified = true; } } return modified; }
retainAll 删除除集合中外的其他元素,batchRemove同上
public boolean retainAll(Collection<?> c) { Objects.requireNonNull(c); return batchRemove(c, true); }
clear 清空数组
public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; }
将size之外的数组内容移除
public void trimToSize() { modCount++; if (size < elementData.length) { elementData = (size == 0) ? EMPTY_ELEMENTDATA : Arrays.copyOf(elementData, size); } }