3.LinkedList源码解析

92 阅读2分钟

一、LinkedList类图总览

Image.jpg

  • LinkedList实现了List、Serializable、Cloneable、Deque接口,和ArrayList相比少了RandomAccess接口,也说明了LinkedList和ArrayList很大一点不同,不支持随机访问。
  • LinkedList实现Deque接口,提供了双端队列的功能。LinkedList支持快速的在头尾添加元素和读取元素。
  • LinkedList基于节点实现双向链表的List每个节点都只想前一个和后一个节点从而形成链表。

二、属性

Image [2].jpg

LinkedList一共有3个属性

通过Node节点指向前后节点形成双向链表

first和last属性:链表的头尾指针

size属性:链表的节点数量,通过其进行计数,避免每次遍历链表获取大小。

Node节点:说到LinkedList我们 一直都在说Node节点。其实Node几点就是LinkedList的静态内部类。

内部维护的当前节点的元素,和前一个节点的引用及后一个节点的引用

/**
 * 节点
 *
 * @param <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;
    }

}

三、构造方法

LinkedList一共有两个构造方法

/**
 * Constructs an empty list.
 */
public LinkedList() {
}

/**
 * Constructs a list containing the elements of the specified
 * collection, in the order they are returned by the collection's
 * iterator.
 *
 * @param  c the collection whose elements are to be placed into this list
 * @throws NullPointerException if the specified collection is null
 */
public LinkedList(Collection<? extends E> c) {
    this();
    // 添加 c 到链表中
    addAll(c);
}

构造方法,没什么好说的

四、linkLast()添加节点

/**
 * Links e as first element.
 */
private void linkFirst(E e) {
    // 记录原 first 节点
    final Node<E> f = first;
    // 创建新节点
    final Node<E> newNode = new Node<>(null, e, f);
    // first 指向新节点
    first = newNode;
    // 如果原 first 为空,说明 last 也为空,则 last 也指向新节点
    if (f == null)
        last = newNode;
    // 如果原 first 非空,说明 last 也非空,则原 first 的 next 指向新节点。
    else
        f.prev = newNode;
    // 增加链表大小
    size++;
    // 增加数组修改次数
    modCount++;
}

/**
 * Links e as last element.
 */
void linkLast(E e) {
    // 记录原 last 节点
    final Node<E> l = last;
    // 创建新节点
    final Node<E> newNode = new Node<>(l, e, null);
    // last 指向新节点
    last = newNode;
    // 如果原 last 为 null ,说明 fast 也为空,则 fast 也指向新节点
    if (l == null)
        first = newNode;
    // 如果原 last 非 null ,说明 fast 也非空,则原 last 的 next 指向新节点。
    else
        l.next = newNode;
    // 增加链表大小
    size++;
    // 增加数组修改次数
    modCount++;
}
  • 记录原来的first、last节点

  • 创建新节点,并将first、last执行新节点

  • 增加链表大小,增加数组修改次数

五、总结

  1. LinkedList基于几点实现双向链表的List,每个节点都指向前一个和后一个节点从而形成链表
  2. Linked提供队列(根据first节点实现)、双端队列(根据fist + last节点实现)、栈的功能(根据last节点实现)
  3. LinkedList随机访问平均时间复杂度是O(n),查找指定元素的平均时间复杂度是O(n)
  4. LinkedList由于底层基于链表实现,查询速度慢,增加和删除效率较高。