GO进阶训练营
// 添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
复制代码
-
接着看确认容量的函数ensureCapacityInternal
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } 复制代码
-
实质上调用的是ensureExplicitCapacity办法,参数为calculateCapacity办法的返回值
// 用于计算容量 private static int calculateCapacity(Object[] elementData, int minCapacity) { // 当elementData还是空数组即第一次add时,将容量置为默许初始容量10 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } // 否则容量为size+1 return minCapacity; } 复制代码
// 用于扩容 private void ensureExplicitCapacity(int minCapacity) { modCount++; // 主要用于迭代时判别能否有被修正而抛异常 // overflow-conscious code // 这里只会第一次和后面size超越数组自身容量才会扩容 if (minCapacity - elementData.length > 0) grow(minCapacity); } 复制代码
-
接着看实质上调用的扩容办法grow,每次扩容都是之前容量的1.5倍
// 扩容,初次为10、后面为之前的1.5倍 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; // 初始时elementData为空数组,这里为0 int newCapacity = oldCapacity + (oldCapacity >> 1); // 扩容为1.5倍 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); } 复制代码
3.3 remove(int index)
-
删除指定位置index,实质上是System.arraycopy复制,相当于移位
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; } 复制代码
3.4 remove(E element)
-
删除指定元素(当有多个,只会移除最前面的一个)
// 遍历,找出相等的第一个元素运用fastRemove移除 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; } // 跟remove(index)大致相同,只是少了rangeCheck和返回值(毕竟不需求) 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 } 复制代码