ArrayList和LinkedList的区别

本文为个人总结,如有错误请评论区指出

文章目录

底层数据结构区别

ArrayList底层实现

ArrayList 基于动态扩容数组(Object\[\])实现

Java中普通数组 的长度是固定不变 的,ArrayList对数组做了封装,当存入元素超过数组容量时,会自动触发扩容机制 :创建一个更大的新数组(默认扩容为原数组大小的1.5倍),并把原数组的所有元素复制到新数组中

LinkedList底层实现

LinkedList 基于双向循环链表(头节点的 prev 指针指向尾节点,尾节点的 next 指针指向头节点) 实现

链表的存储形式是一个个独立的节点,每个节点包含 当前元素值、前驱节点地址(prev)、后继节点地址(next) 三个部分,所有节点通过地址引用串联起来,内存地址无需连续

内存占用区别

ArrayList :内存占用紧凑、连续,内存利用率高。

缺点:因为是动态数组,会预留一部分容量(空闲数组空间) 用于扩容,这部分空间是冗余内存,如果元素少,冗余内存占比会偏高。

LinkedList :内存占用 离散、更大,内存利用率低。

原因:每个节点除了存储元素本身,还需要额外存储前驱节点地址、后继节点地址两个引用,这是额外的内存开销,元素越多,额外开销越大。

方法调用区别

访问元素

  • ArrayList支持高效随机访问 ,查询效率极高,时间复杂度为O(1)
    原因 :数组是连续的内存空间,底层通过数组下标直接定位元素,一步就能找到目标位置,和数组长度无关

  • LinkedList不支持高效随机访问 ,查询效率低,时间复杂度为O(n)
    原因:链表是离散的节点,没有下标概念。要获取第i个元素,必须从链表的头部或尾部开始逐个遍历节点,直到找到目标元素,元素越多,遍历耗时越长

新增元素和删除元素

在集合的尾部新增或删除元素

  • ArrayList :性能高,时间复杂度为O(1)
    原因 :直接给数组尾部空闲位置赋值即可,不会触发元素移动,只有当数组容量不足时,才会触发一次扩容(复制数组的耗时属于低频开销)
  • LinkedList :性能高,时间复杂度为O(1)
    原因:链表尾部有指针直接指向最后一个节点,新增只需改变尾部节点的引用,删除只需断开尾部节点的关联,无需遍历

结论: 尾部增删元素,两者效率相近

在集合头部或指定位置增删元素

  • ArrayList :效率 ,时间复杂度为O(n)
    原因 :数组是连续内存,在指定位置插入元素时,需要把该位置及之后的所有元素向后移动一位 ;删除元素时,需要把该位置之后的所有元素向前移动一位,元素越多,移动的元素越多,耗时越长。
  • LinkedList :效率 ,时间复杂度为O(1)
    原因 :链表的增删只需要修改相邻节点的引用地址即可,不需要移动任何元素。唯一的耗时是找到这个位置的节点(遍历O(n)),但如果已经拿到目标节点的引用,增删就是O(1)。

结论:中间或头部增删,LinkedList 效率高于 ArrayList。

核心API差异

  1. ArrayList无特有方法,所有方法都来自 List 接口

    ArrayList 只实现了 List 接口,所有方法都是 List 的标准方法(add/get/remove/set等),无独有 API。

  2. LinkedList有特有方法

    LinkedList 同时实现了List + Deque两个接口,既可以当 List 用,也可以当队列、栈用,提供了大量首尾操作的高效 API,这些方法的时间复杂度都是 O(1),是 ArrayList 没有的:

java 复制代码
// 队列相关(先进先出)
boolean offer(E e); // 尾部添加元素
E poll(); // 头部删除元素,队列为空返回null
E peek(); // 头部获取元素,队列为空返回null

// 双端队列首尾操作
void addFirst(E e); // 头部添加
void addLast(E e);  // 尾部添加
E getFirst();       // 头部获取
E getLast();        // 尾部获取
E removeFirst();    // 头部删除
E removeLast();     // 尾部删除

// 栈相关(先进后出)
void push(E e);  // 入栈(等价于addFirst)
E pop();         // 出栈(等价于removeFirst)

如何选择使用哪个

优先选择ArrayList的情况

  1. 业务中查询、遍历操作远多于增删操作
  2. 增删操作只在集合尾部进行;
  3. 对内存占用有要求,要求内存利用率高

优先选择LinkedList的情况

  1. 业务中频繁在集合的中间、头部进行增删操作
  2. 集合中元素数量特别多,且增删频繁,ArrayList 的扩容和元素移动会导致性能急剧下降。
相关推荐
腻害兔2 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社3 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖4 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
维天说7 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zane19948 小时前
并发 vs 并行:别再傻傻分不清了,一文讲透 Java 并发编程的第一课
java·后端
噢,我明白了9 小时前
java中Excel的导入和导出(EasyExcel)
java·开发语言·excel
吠品9 小时前
Zabbix Web界面误报Server未运行的排查与解决
java·服务器·数据库
啊湘9 小时前
天气查询API接口 按月Token鉴权 实时天气 物联网可用 文档齐全
java·后端·struts
Java内核笔记9 小时前
告别十亿美元的错误 : Spring Boot 4 空安全 (JSpecify) 实战
java·spring boot·后端