返回

揭秘 LinkedList 源码:深入理解 Java 容器类的底层实现

Android

技术 | LinkedList:Java 容器类的源码剖析

导言

在 Java 容器类庞大的家族中,LinkedList 作为一种重要的链表结构,以其独特的优点和广泛的应用场景备受青睐。本文将带你踏上一段深入 LinkedList 源码之旅,揭开它的底层实现,全面解析其工作原理,助你深入理解 Java 集合框架。

LinkedList 的结构与特性

LinkedList 是基于双向链表实现的 List 接口,它由一组相互连接的节点组成,每个节点包含一个元素和指向下一个节点的引用。与 ArrayList 等数组结构的 List 不同,LinkedList 在内存中不是连续存储的,因此可以动态地插入和删除元素。

LinkedList 拥有以下特点:

  • 双向迭代: 可以正向和反向遍历链表,方便访问元素。
  • 灵活的插入和删除: 在链表任意位置插入或删除元素的时间复杂度为 O(1),不需要移动其他元素。
  • 内存开销较高: 由于每个节点都需要存储元素和指向下一个节点的引用,因此 LinkedList 的内存开销比 ArrayList 更高。

源码剖析

1. 节点结构

LinkedList 的核心是 Node 类,它定义了链表中每个节点的结构:

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(E element, Node<E> next, Node<E> prev) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}
  • item:存储链表元素。
  • next:指向下一个节点的引用。
  • prev:指向前一个节点的引用。

2. 字段和构造器

LinkedList 类定义了以下字段和构造器:

transient int size = 0;
transient Node<E> first;
transient Node<E> last;

public LinkedList() {
    this(null);
}

public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}
  • size:链表中元素的数量。
  • first:指向链表第一个节点的引用。
  • last:指向链表最后一个节点的引用。
  • 构造器允许通过传入集合来初始化 LinkedList。

3. 添加元素

LinkedList 提供了多种添加元素的方法:

  • addFirst(E e):在链表开头添加元素。
  • addLast(E e):在链表末尾添加元素。
  • add(E e):在链表末尾添加元素。

这些方法通过创建新的 Node 节点并将其链接到链表中来实现添加操作。

4. 删除元素

LinkedList 也提供了多种删除元素的方法:

  • removeFirst():删除链表第一个元素。
  • removeLast():删除链表最后一个元素。
  • remove(Object o):删除指定元素。

这些方法通过修改链表的引用来实现删除操作。

5. 迭代器

LinkedList 提供了 ListIteratorIterator 两种迭代器来遍历链表:

  • ListIterator:可以正向和反向遍历链表,并允许添加和删除元素。
  • Iterator:只能正向遍历链表。

6. 其他方法

LinkedList 还提供了其他一些有用的方法,例如:

  • get(int index):获取指定索引处的元素。
  • set(int index, E element):修改指定索引处的元素。
  • clear():清空链表。

优缺点总结

优点:

  • 灵活的插入和删除操作。
  • 顺序访问性能良好。
  • 支持双向迭代。

缺点:

  • 随机访问性能较差。
  • 内存开销较高。

应用场景

LinkedList 广泛应用于以下场景:

  • 需要频繁插入和删除元素的场景。
  • 需要双向遍历链表的场景。
  • 需要在链表中查找特定元素的场景。

总结

通过对 LinkedList 源码的深入剖析,我们不仅了解了它的底层实现,也理解了它的工作原理。LinkedList 作为 Java 容器类中的一种重要结构,在实际开发中发挥着不可替代的作用。掌握 LinkedList 的特性和用法,将有助于我们编写更高效、更健壮的 Java 程序。