0

0

在Java里ArrayList和LinkedList如何取舍_Java集合选型思路说明

P粉602998670

P粉602998670

发布时间:2026-02-01 15:07:02

|

949人浏览过

|

来源于php中文网

原创

ArrayList随机访问快(O(1)),但中间插入删除慢(O(n));LinkedList增删快(O(1)),但随机访问慢(O(n))、内存开销大、遍历性能差。

在java里arraylist和linkedlist如何取舍_java集合选型思路说明

ArrayList 随机访问快,但中间插入删除慢

如果你频繁调用 get(i)set(i, e),尤其是索引值不固定、需要跳着读写,ArrayList 是更优选择。它底层是数组,O(1) 时间完成定位。

但要注意:在非尾部位置(比如 add(5, e)remove(10))操作时,它得移动后续所有元素。数据量大时,一次 add(index, e) 可能触发 O(n) 位移 —— 这不是“偶尔慢”,而是每次都会发生。

  • 适合场景:日志列表只读展示、缓存预加载后批量遍历、DTO 转换中按序取字段
  • 警惕点:别在 for 循环里边遍历边 remove(),容易漏元素或抛 ConcurrentModificationException
  • 小技巧:如果确定容量,用 new ArrayList(initialCapacity) 避免多次扩容复制

LinkedList 插入删除快,但随机访问代价高

LinkedList 是双向链表,addFirst()addLast()removeFirst()removeLast() 全是 O(1);在已有节点引用时(比如迭代器刚返回的 next() 节点),addBefore()remove() 也是 O(1)。

但它没有下标支持——每次 get(i) 都得从头或尾开始逐个跳指针,平均 O(n/2)。哪怕只是 get(100),也要遍历 100 次指针跳转,比 ArrayList.get(100) 慢一个数量级。

立即学习Java免费学习笔记(深入)”;

InsCode
InsCode

InsCode 是CSDN旗下的一个无需安装的编程、协作和分享社区

下载
  • 适合场景:实现push/pop)、队列(offer/poll)、需要频繁在头部增删的事件缓冲区
  • 注意陷阱:list.get(list.size() / 2) 看似“取中间”,实则是性能雷区
  • 别被名字误导:LinkedList 并不支持高效随机访问,它的 get(int) 方法内部就是循环遍历

别只看增删查,还要看内存和迭代开销

ArrayList 每个元素只存数据本身(如 Integer 引用),而 LinkedList 每个元素额外包两层对象:一个 Node 实例,含 prevnextitem 三个字段。10 万个元素,LinkedList 多占几 MB 内存很常见。

迭代行为也不同:ArrayList.iterator() 返回的是轻量级内部类,hasNext()/next() 几乎无额外开销;LinkedList.iterator() 每次都要维护当前节点引用,且因 CPU 缓存不友好(节点内存不连续),遍历速度反而更慢。

  • 内存敏感场景(如 Android 低配设备、嵌入式 Java):优先 ArrayList
  • 大量 for (E e : list) 场景:两者性能差距比单次 get() 更明显
  • subList() 行为差异:ArrayList.subList() 返回的是视图,修改影响原列表;LinkedList.subList() 同样是视图,但其 add() 会触发整段重建,意外开销更大

真要中间插入?先考虑替代方案

如果业务逻辑确实要求“在列表中间高频插入/删除”,LinkedList 很少是最佳解。JVM 对数组操作做了深度优化,而链表破坏了局部性,现代 CPU 架构下反而吃亏。

更实用的做法是:用 ArrayList + 标记删除(逻辑删)、延迟整理;或者改用 TreeSet / LinkedHashSet 维护有序性;甚至直接上 ArrayDeque(如果只需要头尾操作)。

  • 别为了“理论复杂度”选 LinkedList,实际压测 ArrayList.add(500, e)LinkedList.add(500, e) 在万级数据下的耗时,结果常让人意外
  • 如果插入位置有规律(如总在前 10% 或后 10%),可以拆成两个 ArrayList,避免全局位移
  • JDK 21 的 SequencedCollection 接口统一了顺序集合行为,但底层实现没变——选型逻辑依然取决于你真正怎么用

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

503

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

545

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

113

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

200

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1180

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

235

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2158

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.19

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

30

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.1万人学习

C# 教程
C# 教程

共94课时 | 8.2万人学习

Java 教程
Java 教程

共578课时 | 55万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号