1、插入
1.1、ArrayList实现
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* 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++;
}
1.2、LinkedList实现
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
/**
* 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) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
1.3、对比
ArrayList插入时,先将插入下标之后的所有元素往后复制一遍(下标+1);然后再将元素设置到指定下标。
LinkedList插入时,先根据值创建节点元素;然后修改插入位置前后节点的索引。
总结:ArrayList在插入时比LinkedList多进行了元素的复制,会消耗一定的时间,在插入元素时比LinkedList性能要低。
2、删除
2.1、ArrayList实现
/**
* Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their
* indices).
*
* @param index the index of the element to be removed
* @return the element that was removed from the list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
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;
}
2.2、LinkedList实现
/**
* Removes the element at the specified position in this list. Shifts any
* subsequent elements to the left (subtracts one from their indices).
* Returns the element that was removed from the list.
*
* @param index the index of the element to be removed
* @return the element previously at the specified position
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
/**
* Unlinks non-null node x.
*/
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
2.3、对比
ArrayList删除时,先将插入下标之后的所有元素往前复制一遍(下标-1);然后将元素置空,并减少List长度。
LinkedList删除时,将删除节点的前节点指针指向后节点,然后将元素置空,并减少List长度。
总结:ArrayList在删除时比LinkedList多进行了元素的复制,会消耗一定的时间,在删除元素时比LinkedList性能要低。
3、查询
3.1、ArrayList实现
E elementData(**int **index) { **return **(E) **elementData**[index]; }
3.2、LinkedList实现
_/** __ * Returns the (non-null) Node at the specified element index. __ */ _Node<E> node(**int **index) { _// assert isElementIndex(index); __ __ _**if **(index < (**size **>> 1)) { Node<E> x = **first**; **for **(**int **i = 0; i < index; i++) x = x.**next**; **return **x; } **else **{ Node<E> x = **last**; **for **(**int **i = **size **- 1; i > index; i--) x = x.**prev**; **return **x; } }
2.3、对比
ArrayList查询定位时,直接根据数组索引获取元素。
LinkedList查询定位时,需要遍历到指定的位置获取元素。
总结:ArrayList在查询时比LinkedList少了元素遍历,比LinkedList性能要高。