LinkedList 是线程不安全的,允许节点为null的双向链表。 其底层数据结构是链表,它实现List, Deque, Cloneable, java.io.Serializable接口,它实现了Deque,所以它也可以作为一个双端队列。
面试点
- LinkedList 与 ArrayList的区别
1、LinkedList 没有实现RandomAccess接口,且底层数据结构是链表,所以随机访问元素速度较慢;ArrayList 实现RandomAccess 接口,且底层数据结构是数组,所以随机访问元素速度较快。
2、LinkedList 查询效率较低,但增删的效率较高,原因是其底层数据结构是链表,增删只需要移动指针,并也不需要扩容,空间效率比ArrayList 高。ArrayList 底层数据结构是数组,执行随机访问,查询效率较高。
- LinkedList 随机访问元素的算法
根据index 与size 判断其在链表的前半段还是后半段,然后再顺序查找。所以LinkedList 随机访问元素效率很低。
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
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;
}
}
成员变量
允许节点为null
transient int size = 0;
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;
构造函数
基本没啥
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
节点Node 的数据结构
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;
}
}