Java学习随笔:ArrayList 与 LinkedList 到底怎么选(2026-09-18)

学习集合的时候,ArrayList 和 LinkedList 是我最先接触到的两个 List 实现,也是面试里经常被拿来比较的一对“老朋友”。它们都实现了 List 接口,从使用上看差别不大,都可以按顺序存放元素、按索引访问、支持增删改查。可一旦追问底层结构,区别就非常明显:ArrayList 基于动态数组,LinkedList 基于双向链表。正是这两种不同的底层结构,决定了它们在不同场景下的性能表现。

先说 ArrayList。它的内部是一个可以自动扩容的数组,元素在内存中是连续存放的。因为连续存储,ArrayList 通过下标访问元素非常快,可以直接按照“起始地址加下标乘元素大小”算出位置,时间复杂度是 O(1)。但数组连续存储也带来一个代价:当数组装满需要扩容时,要重新申请一块更大的空间,并把旧数据复制过去;而在中间插入或删除元素时,后面的元素都要整体移动,最坏情况是 O(n)。所以 ArrayList 更适合“读多写少”、而且主要是往末尾追加的场景。

LinkedList 则是另一套思路。它用一个个节点把元素串起来,每个节点除了保存数据,还保存指向前后节点的引用。这样在中间插入或删除元素时,只需要修改相邻节点的引用,不用移动大量数据,时间复杂度是 O(1)。但链表没有下标这种“直达”能力,访问第 n 个元素必须从头或从尾开始一个节点一个节点地找,时间复杂度是 O(n)。因此 LinkedList 更适合需要频繁在头部或中间插入删除的场景,而对随机访问并不友好。

不过,这里的 O(1) 和 O(n) 只是理论上的说法,实际使用中还要考虑很多因素。比如在 LinkedList 中间插入元素,虽然修改节点的操作是 O(1),但要先遍历到指定位置,这部分仍然是 O(n);ArrayList 虽然在中间插入要移动元素,但现代计算机对连续内存的访问有缓存优势,元素搬移常常比想象中快。所以很多情况下,即使做了不少插入删除,ArrayList 的实际表现也不一定差。

除了性能,两者还有使用习惯上的差异。ArrayList 支持随机访问接口,遍历时用普通 for 循环和迭代器都很自然;LinkedList 则额外实现了 Deque 接口,可以当作栈或队列使用,这在需要先进先出或后进先出的场景里很方便。工程上,如果只是需要一个普通列表,大多数时候直接选 ArrayList 就够用了;只有明确存在大量头尾增删的需求时,再考虑 LinkedList 或更合适的 Deque 实现。

这次比较让我体会到,选数据结构不能只看接口,更要看数据量、访问方式和增删频率。ArrayList 和 LinkedList 没有绝对的好坏,只有是否适合当前场景。理解了底层结构,再回头看那些关于“什么时候用谁”的题目,答案就不再是死记硬背,而是从内存布局和复杂度推导出来的自然结论。

posted @ 2026-09-18 22:15  梦幻泡影Qv'Q  阅读(4)  评论(0)    收藏  举报