1.3 LinkedList 源码 + 解析

4 阅读1分钟

1.3.1 底层双向链表结构

// 双向链表节点
private static class Node<E> {
    E item; // 存储元素
    Node<E> prev; // 前驱节点指针
    Node<E> next; // 后继节点指针
    Node(Node<E> prev, E element, Node<E> next) {
        this.prev = prev;
        this.item = element;
        this.next = next;
    }
}
transient Node<E> first; // 头节点
transient Node<E> last; // 尾节点
transient int size;
transient int modCount;

文字解释:双向链表保存头尾指针,头尾增删仅修改指针 O (1),按下标查找需要遍历。

1.3.2 按下标查找优化 node ()

Node<E> node(int index) {
    // 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;
    }
}

1.3.3 场景对比 ArrayList vs LinkedList

  1. 优先 ArrayList:随机查询、尾部新增、循环遍历(数组连续内存,CPU 缓存友好);
  2. 仅 LinkedList:频繁头尾插入删除、几乎无查询场景。