ArrayList和LinkedList内部的实现原理和区别

一、内部实现原理

ArrayList

它的底层基于‌动态扩容的Object数组‌实现,内存是连续分布的:

无参构造初始化时默认是空数组,第一次添加元素才会将容量初始化为10

当数组容量不足时,会自动扩容为原容量的1.5倍,通过创建新数组、批量拷贝旧元素完成扩容

依托数组的下标索引特性,天然支持O(1)时间复杂度的随机访问

LinkedList

它的底层基于‌双向链表‌实现(JDK1.6之后废弃了旧版本的双向循环链表),内存不需要连续分布:

内部定义了独立的Node节点类,每个节点同时存储元素数据、指向前驱节点的prev指针、指向后继节点的next指针

没有数组扩容机制,新增/删除元素时仅需要修改相邻节点的指针指向,不需要批量移动数据

不支持直接通过下标定位元素,访问指定位置元素时需要从头部或尾部开始遍历链表查找

二、核心区别对比

访问性能‌

ArrayList通过数组下标直接定位元素,查询、修改操作的时间复杂度为O(1);LinkedList必须遍历链表才能找到目标元素,随机访问的时间复杂度为O(n),性能远低于ArrayList。

增删性能‌

ArrayList在数组中间插入/删除元素时,需要移动后续所有元素来维持数组连续性,大数据量下性能开销很高;LinkedList在已知目标位置的前提下,仅需修改前后节点的指针即可完成增删,操作效率更高。

注意:如果是在列表尾部追加元素,两者性能几乎没有明显差异。

内存占用‌

ArrayList的内存结构紧凑,仅会因扩容预留少量冗余容量,没有额外的额外开销;LinkedList的每个节点都需要额外存储两个指针,同等数据量下占用的内存远高于ArrayList。

线程安全‌

两者都没有做同步锁控制,都是非线程安全的集合,多线程并发读写场景下容易出现数据覆盖、数组越界等异常。

三、适配场景

优先选择ArrayList的场景‌

90%以上的常规业务场景都推荐使用它,尤其是以高频随机查询为主、增删操作大多集中在列表尾部的场景,比如业务数据分页返回、常规列表数据遍历处理,它的查询性能和内存利用率都更有优势。如果提前预知数据量大小,还可以手动指定初始容量,避免频繁扩容带来的性能损耗。

选择LinkedList的场景‌

仅适合需要频繁在列表头部、中间位置执行插入/删除操作的场景,比如实现FIFO队列、栈结构,或者需要频繁在列表中间动态插入元素的算法场景,这类场景下LinkedList的增删效率优势才能充分体现。

相关推荐
头发还在的女程序员1 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats2 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
我命由我123452 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
都叫我大帅哥4 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.5 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
腻害兔6 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:IM 即时通讯模块,一个被低估的「全功能聊天系统」
java·前端·vue.js·产品经理·ai编程
心念枕惊6 小时前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
景同学8 小时前
把 AI 用到线上运维:可行、有效,前提是喂足信息——一次 Full GC 排障实录
java·人工智能·后端
C++、Java和Python的菜鸟8 小时前
第7章 后端Web实战(Tlias系统)
java
憧憬成为java架构高手的小白9 小时前
黑马八股--spring框架学习
java·学习·spring