为了账号安全,请及时绑定邮箱和手机立即绑定

Java ArrayList vs LinkedList:一场“链表”和“数组”的街头巷战

标签:
Java JavaScript

原文来自于:https://zha-ge.cn/java/51

Java ArrayList vs LinkedList:一场“链表”和“数组”的街头巷战

大家好啊!今天想和你们聊聊 ArrayList 和 LinkedList。这两个家伙在 Java 集合圈混迹多年,一个是看似无害的“数组党”,另一个则是自诩灵活的“链表帮”。大多数人可能随手 new 个 ArrayList 就开工了,LinkedList 只有在用队列或者 LRU 缓存那点场合才会想到。但你有没有认真琢磨过:为啥有两个 List 实现?底层到底区别在哪儿?我的选择会不会埋下什么性能地雷?

下面就来听听我的“踩坑血泪记”吧!😅


酒桌开局:谁快,谁慢?

说实话,刚学集合那会儿我完全不在意底层原理。谁让 List 方法名都一样!结果一次搞面试手撕代码,遇到了加班批量 add(),妥妥地催生了一场ArrayList vs LinkedList的惨烈大战。

我们先来聊聊:

  • ArrayList 本质其实就是个会自动扩容的 Object 数组。用下标随便拿,特别带感;
  • LinkedList 是典型的双向链表,增删元素砍瓜切菜,随地插拔不眨眼。

你以为这样就完事了?No, 朋友,细节才是魔鬼。


踩坑瞬间

轮到重头戏了!

那一次,我手里有几万个对象要批量插入和删除,而且操作位置还没那么规律(有头有尾还有中间)。一开始我自信满满地选择了 LinkedList,心说“插入/删除这不是链表的地盘嘛!”

结果数据一多,发现程序……卡得像在跑 Windows 98。抓起 JProfiler 一看,get(index) 成了大头。仔细想,哎呀,链表随机访问可是要一层层 next 找过去的啊。这一下醒悟:

LinkedList 的 get(int index) 是 O(n) 复杂度,ArrayList 可是 O(1)!

下面献上一段让我梦回“Java 黑历史”的经典踩坑代码片段:

for (int i = 0; i < list.size(); i++) {
    Object obj = list.get(i);  // LinkedList 这里惨烈 O(n)
    // ...
}

再别说你还在链表里写各种 for 循环遍历了,简直是“CPU 杀手”!

顺便插句话,ArrayList 每次 add 超了容量,都会“扩容”,核心逻辑其实就是下边这样:

// ArrayList 扩容精粹
Object[] newArray = new Object[oldArray.length * 1.5];
// System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
// ...

平时不用想,但插入很多大量数据时就感觉好像钱包被偷偷割了一刀:卡。


洞察&脑洞时间

知道真相的我,开始总结自己踩过哪些经典坑:

场景 ArrayList LinkedList
随机访问 快速O(1) 龟速O(n)
尾部插入 超快,偶尔需扩容 不慢
中间插入/删除 低效(大量元素搬家) 优势(只改指针)
作为队列/双端队列 一般(实现麻烦) 直接支持

所以别再迷迷糊糊“谁都用 ArrayList”了,根据业务场景选工具才是正道!


经验启示

每次被“无脑用 ArrayList”坑后,回头看其实很好笑。简单总结:

  1. 大部分场景都直接选 ArrayList,真需要链表特性的(例如大量头部插入、双端操作,或者需要 Deque 方法),才考虑 LinkedList;
  2. 遍历/查找为主的用 ArrayList,别拿 LinkedList 做大量 get(index) 了;
  3. 链表不是全能的,能不用就别用,尤其在多线程/缓存敏感场景。

最后再丢一个敲门砖:如果需求是“增删改查全家桶”,确定好你的主要瓶颈在哪。能用 ArrayList 绝不造轮子,不过偶尔也要考虑一下更有趣的新 List,比如 CopyOnWriteArrayList、或者干脆动用 Guava 的各种集合。


讲真,这俩类就像是老街区的两家早餐铺,想吃包子还是油条?务必下嘴前想明白自己的胃!
下次聊点更劲爆的集合骚操作~

收藏+关注,帮你远离无聊的踩坑!👻

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消