本质区别是arraylist基于连续内存的动态数组,linkedlist基于离散内存的双向链表;前者支持o(1)随机访问、遍历缓存友好,后者增删指针操作o(1)但查找需o(n),内存开销更大。

本质区别就一点:ArrayList 用的是连续内存的动态数组,LinkedList 用的是离散分布的双向链表节点。这个根本差异直接决定了它们在内存布局、访问方式、增删逻辑和性能表现上的全部不同。
内存布局:一块整地 vs 零散小屋
ArrayList 的所有元素挤在一段连续的内存里,就像一排紧挨着的房间,编号从 0 开始。CPU 缓存能一次加载多个相邻元素,遍历起来特别快。
LinkedList 每个元素单独住一间“小屋”(Node 对象),屋子之间靠前后指针(prev / next)连成一条线。这些小屋在内存里天南海北,没有固定顺序,缓存命中率低,遍历时容易频繁换页。
这意味着:哪怕只存 10 个元素,ArrayList 占用的是连续的一小片空间;LinkedList 却要分配 10 个独立对象,每个还额外带两个引用字段——内存开销明显更大。
访问机制:直接定位 vs 循路找人
ArrayList 的 get(int index) 是“查户口”:已知编号,直接算出地址(elementData[index]),一步到位,O(1)。
LinkedList 的 get(int index) 是“问路找人”:先判断从头走近还是从尾走近,再顺着 next 或 prev 一个一个问下去,平均要走一半路程,O(n)。
所以哪怕你只是想取第 50 万个元素,ArrayList 依然飞快;LinkedList 却得老老实实数 25 万次指针跳转。
增删逻辑:挪动人群 vs 拆桥修路
ArrayList 在中间插入或删除时,核心动作是 移动后续所有元素:比如在索引 3 插入,索引 3 到末尾的所有元素都要往后/往前挪一位,靠 System.arraycopy 完成,耗时集中在数据搬移。
LinkedList 在已知位置增删时,核心动作是 改几个指针:找到前驱节点后,新建节点,把前驱的 next、原后继的 prev、新节点的 prev/next 全部重新连好,不碰其他节点,指针调整本身是 O(1)。
但注意:LinkedList 的“已知位置”不免费——你要先花 O(n) 时间找到那个位置。所以对按索引操作(如 add(100, x)),它实际仍是 O(n)。
容量管理:主动扩容 vs 按需建房
ArrayList 有明确的“容量(capacity)”概念。初始默认 10(JDK8 起懒加载),满了就申请一块更大的连续内存(1.5 倍),把老数据复制过去。扩容是重量级操作,但摊还下来平均仍是 O(1)。
LinkedList 没有容量一说。每 add 一个元素,就 new 一个 Node 对象,堆上零散分配,无需预估大小,也不用复制迁移。灵活,但对象创建和 GC 压力略高。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











