Add
首次add 元素需要对数组进行扩容(初始化Capacity 10, 第二次扩容10>>1 为5, 第三次扩容15>>1 为7), 每次扩容之前长度的1.5倍,当add 的数据较多时扩容较为频繁,这时建议在new ArrayList() 指定初始容量 或者 使用 linkedList
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } // 确定内存容量 private void ensureCapacityInternal(int minCapacity) { //minCapacity=1 增加的容量 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // DEFAULTCAPACITY_EMPTY_ELEMENTDATA=10 //默认的容量 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } // 明确容量 ensureExplicitCapacity(minCapacity); // minCapacity=10 } /** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. * 确保数组中的容量能存储的下新增的容量,不足则扩容 * @param minCapacity the desired minimum capacity */ private void grow(int minCapacity) { //minCapacity=10 // overflow-conscious code int oldCapacity = elementData.length; //oldCapacity =0 int newCapacity = oldCapacity + (oldCapacity >> 1); //newCapacity =0 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //newCapacity =10 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 对原数组进行扩容 }
remove
除非是当前数组中只剩下一个元素,否则每次remove 都会 System.arraycopy 移动元素。
如果是remove(obj) 需要每次遍历数组找到equals的对象,然后 System.arraycopy 移动元素。
LinkedList 虽然不用移位,但也每次都要变量链表,更改引用对象 public E remove(int index) { rangeCheck(index); // 校验要删除的索引是否超出范围 modCount++;// 操作count++ E oldValue = elementData(index);// 取出要删除的元素 int numMoved = size - index - 1; // 得出要移动元素个数 if (numMoved > 0) // 移动元素 System.arraycopy(elementData, index+1, elementData, index, numMoved); // 将删除的元素置为null elementData[--size] = null; // clear to let GC do its work return oldValue; }
get
E elementData(int index) { // 直接根据索引获取元素 return (E) elementData[index]; }