ArrayList和Vector都实现了RandomAccess接口,而LinkedList没有,RandomAccess接口是一个空接口,所以它没有实际意义,就是一个标记,标记这个类支持快速随机访问,所以,arrayList和vector是支持随机访问的,但是LinkedList不支持。ArrayList和LinkedList做末尾add操作,ArrayList性能可能更高,由于LinkedList在add时候需要更多的对象创建和赋值操作。
LinkedList 使用双向链表实现存储。
经常对数组做随机插入操作,特别是插入的比较靠前,那么LinkedList的性能优势就非常明显,而如果都只是末尾插入,则ArrayList更占据优势,如果需要线程安全,则Vector更好。
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; } }
从以上代码可以看出它的节点类是一个双链表。
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; } }
这里的小技巧:index 在前半段还是后半段,来决定是从前向后搜索,还是从后向前。
LinkedList中有很多功能相同的方法,这是为了实现不同的接口。
取元素第一个元素:
public E peek():找到返回头元素,没找到返回空。不会删除头元素。
public E element():找到返回头元素,没找到抛出NoSuchElementException。不会删除头元素。
public E poll():找到返回头元素,没找到返回空。会删除头元素。
public E remove():找到返回头元素,没找到抛出NoSuchElementException。会删除头元素。
增加一个元素:
public boolean add(E e):始终返回true;
public boolean offer(E e):直接调用了add
public E get(int index) { checkElementIndex(index); return node(index).item; }
返回特定位置上的元素。
LinkedList为Stack、Deque、Queue的操作都做了准备。LinkedList 可以被当作堆栈和队列来使用。
Deque接口继承了Queue接口,而Queue接口继承了Collection接口,LinkedList实现了Deque接口;关系很明显了吧 (顶级接口)Collection–>Queue–>Deque–>LinkedList(实现类)。