2019独角兽企业重金招聘Python工程师标准>>>
public class Test1 {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("abc");
list.add("hello");
list.remove("abc");
}
}
这是最简单的一个添加操作,查看list.add源代码:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return true (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
其中size大小默认为0,所以传递过去的参数为1
查看ensureCapacityInternal()源代码
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
而现在elementData为[],EMPTY_ELEMENTDATA也为[],所以进入if中,DEFAULTY_CAPACITY默认为10,minCapacity为1,所以minCapacity最终值为10
ensureExplicitCapacity源代码为:
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
当前elementData.length为0,所以进入if中直行grow(minCapacity)
/**
* 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) {
// 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);
}
最后将重新复制原数组以newCapacity为大小的elementData属组。此时elementData中的元素为[null,null,null,null,null,null,null,null,null,null]
然后直行到最开始的代码 list.add("abc");
这时elementData中的元素为[abc, null, null, null, null, null, null, null, null, null]
接下来我们看看list.remove("abc")
/**
* Removes the first occurrence of the specified element from this list,
* if it is present. If the list does not contain the element, it is
* unchanged. More formally, removes the element with the lowest index
* i such that
* (o==null ? get(i)==null : o.equals(get(i)))
* (if such an element exists). Returns true if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
*
* @param o element to be removed from this list, if present
* @return true if this list contained the specified element
*/
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;
}
首先判断删除的元素是否为空,如果不为空那么执行fastRemove(index)
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
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
}
System.arraycopy(elementData, index+1, elementData, index,numMoved); elementData[--size] = null;
其中System.arraycopy()的意思是:public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。
所以上面两句话的意思是将elementData中index之后的位置依次移动到前一个位置。效率非常低。
我们看看add(index,element)方法
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
与remove方法很相似。涉及到数组的移动。
所以ArrayList的添加和删除操作时,会涉及到数组的复制,这是个成本很高的操作。
优点:
ArrayList执行查询的速度是非常快的,因为底层采用的是数组,而数组是根据下标索引来执行查找的。