一、简介
LingkedList
是 Java 集合框架中一个常用的类,它实现了 List
、Queue
和 Serializable
接口。底层使用 双向链表 作为数据结构。
特点:
特性
描述
增删操作快
插入、删除节点时不需要移动元素,效率高
查询效率低
查询元素需要从头或尾部一个个遍历
线程不安全
多线程环境下需手动同步或使用 Collections.synchronizedList
包装
二、底层结构
LinkedList
的核心是一个内部静态类 Node<E>
:
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; } }
成员变量
transient int size = 0 ;transient Node<E> first;transient Node<E> last;
first
:指向链表的头结点
last
:指向链表的尾结点
size
:链表元素个数
整个链表通过节点的 next
和 prev
字段形成双向连接。
三、常用方法
add(E e)
public boolean add (E e) { linkLast(e); return true ; } 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++; }
将元素添加到链表末尾,如果链表为空,则 first
和 last
都指向新节点。
remove()
public E remove () { return removeFirst(); } public E removeFirst () { final Node<E> f = first; if (f == null ) throw new NoSuchElementException (); return unlinkFirst(f); } private E unlinkFirst (Node<E> f) { final E element = f.item; final Node<E> next = f.next; f.item = null ; f.next = null ; first = next; if (next == null ) last = null ; else next.prev = null ; size--; return element; }
从链表头部删除元素,同时更新 first
指针。
get(int index)、node(int index)
public E get (int index) { checkElementIndex(index); return node(index).item; } Node<E> node (int 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; } }
查询时,LinkedList
会根据索引判断从头还是从尾开始遍历,优化性能。
安全校验
private void checkElementIndex (int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException (outOfBoundsMsg(index)); } private boolean isElementIndex (int index) { return index >= 0 && index < size; }
在访问元素之前,会先校验是否越界,防止访问非法位置导致程序崩溃。
四、注意事项
不要使用 LinkedList
来频繁随机访问元素。
如果是栈、队列或双端队列操作,LinkedList
是一个很好的选择。
Java 8 之后建议使用 ArrayDeque
替代 LinkedList
实现队列,性能更优。
总结
LinkedList
是基于 双向链表 实现的,适用于 频繁插入删除 的场景。
每个节点包含三个属性:当前元素、前一个节点引用、后一个节点引用。
查询操作性能相对较低,但可以通过判断位置优化遍历方向。