一、概述
LinkedList的底层存储结构是双向链表实现的。链表无容量限制,并且在中间插入和删除的效率高于数组,因为它只需要找到该结点,通过将其前一个结点next指向后一个结点,后一个结点的prev指向前一个结点,即可完成删除操作。
但链表结构的缺点在于:
- 其需要额外的链表指针,用于存储next和prev。
- 无法直接获得指定位置的节点,只能从头遍历或从尾结点遍历得到对应结点的值。
LinkedList中静态内部类结构:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
LinkedList结构的简单结构如下:(图片来源于github.com/LRH1993/and…)
二、set和get方法
public E set(int index, E element){
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}public E get(int index){
checkElementIndex(index);
return node(index).item;
}这两种方法都是调用node()方法,该方法以O(n/2)的性能来获取一个结点。具体如下:
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;
}
}即判断从头结点开始遍历查找,还是从尾结点遍历查找该结点,以便提高查找效率。
三、add()方法
- add(E element);
public boolean add(E e){
linkLast(e);
return true;
}- add(int index, E element);
public void add(int index, E element){
checkPositionIndex(index);
if(index == size)
linkLast(element);
else
linkBefore(element, node(index));
}这两种方法插入元素中,要么调用linkLast()方法,要么调用linkBefore()方法,前一种是直接在尾结点出进行插入,后一个方法找到对应的位置node(index)结点,在前前面插入对应的结点。