Java LinkedList的节点在堆内存中分散、非连续存储,通过prev/next引用逻辑串联,首尾由first/last字段直接指向,支持O(1)首尾增删但随机访问为O(n)。

Java 中 LinkedList 的链表节点在内存中是分散、非连续地存储在堆(Heap)上的,每个节点独立申请内存空间,靠引用(指针)相互连接,而非像数组那样占据一块连续区域。
节点本身结构决定存储方式
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;
}
}这意味着每个 Node 对象包含三部分:
- 一个泛型数据
item - 两个对象引用
prev和next(可能为null)
这些字段共同构成一个普通 Java 对象,由 JVM 在堆中动态分配内存。
立即学习“Java免费学习笔记(深入)”;
实际内存布局特点
-
物理地址不连续:JVM 每次调用
new Node(...)时,从堆中找一块可用内存,位置由垃圾回收器和内存分配策略(如 TLAB)决定,两次分配的Node很可能相隔很远。 -
逻辑顺序靠引用维持:虽然
Node A和Node B在内存里离得远,但只要A.next指向B的地址,它们就算“连在一起”,形成逻辑上的线性序列。 -
首尾有快速入口:
LinkedList类维护两个transient字段 ——first和last,分别直接持有头节点和尾节点的引用,避免每次操作都从头遍历。
举个具体例子
假设执行:
LinkedList<String> list = new LinkedList<>();
list.add("A");
list.add("B");
list.add("C");内存中大致分布如下(地址示意):
| 内存地址 | 内容 |
|---|---|
0x1000 |
Node{ item="A", prev=null, next=0x2000 } |
0x2000 |
Node{ item="B", prev=0x1000, next=0x3000 } |
0x3000 |
Node{ item="C", prev=0x2000, next=null } |
list.first 存的是 0x1000,list.last 是 0x3000,size = 3。整个链表靠这三个字段 + 各节点间的 prev/next 引用维系结构。
和 ArrayList 的关键区别
-
ArrayList:一个Object[] elementData数组,所有元素挤在同一块连续内存里,靠下标算地址。 -
LinkedList:多个Node对象散落在堆各处,靠引用来“串起来”,增删只需改几个引用,不用搬动数据。
这种设计让插入删除快(尤其首尾),但随机访问慢(必须从头或尾一步步跳转)。


















