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];
}