ArrayList 和 LinkedList 之间应该怎么选择

news2024/11/26 8:56:42

这篇文章是来自知乎上的一个问题。

相信很多人在面试时都被问过这个问题,然后一般回答:ArrayList在指定下标访问时快,LinkedList在插入/删除元素时快。

其实这是一种人云亦云的谬误。可能最初有人这么回答,然后不加验证地转来转去,后面就成了八股文中的“标准答案”。

这个问题其实早在2015年,就由作者Joshua Bloch在Twitter上给出了回答:“有人真的使用过LinkedList吗?我写了它,但是我从没用过”。

请添加图片描述

以下是我在知乎上的回答。

——————————————————————————————————————————————————————————

先说结论:需要List的场合,绝大部分情况下选择ArrayList;需要Queue或Stack的场合,绝大部分情况下选择ArrayDeque

看实际的性能测试。对ArrayList和LinkedList分别做100000次以下操作,统计执行时间(ms):

尾部插入头部插入中间插入遍历
ArrayList53461527
LinkedList2450442

逐条分析解释:

  1. 尾部插入:相差不大,都是O(1)的操作。
  2. 头部插入:LinkedList明显优于ArrayList。因为ArrayList每次操作都涉及底层全量数组的System.arraycopy();而LinkedList是双向链表,内存保存了headNode,所以是O(1)的操作。
  3. 中间插入:ArrayList明显优于LinkedList。因为LinkedList每次需要遍历寻找插入节点,仅这一步复杂度就是O(n)。
  4. 遍历:相差不大。

除了上述时间消耗的比较,在空间消耗上ArrayList也优于LinkedList。虽然ArrayList会扩容到1.5倍,但是LinkedList内部为每个存储元素封装了Node对象,除了Node对象头部,还要保存前后Node的地址和当前存储元素的地址,实际上LinkedList占用内存要远大于ArrayList。

结论:仅在头部插入/删除时,LinkedList在时间上有性能优势。

不过问题来了:既然你需要在头部频繁插入/删除,那么为什么不选择更合适的数据结构呢?比如Stack或者Queue。

那么LinkedList是实现这两种数据结构的最优选择吗?答案也不是,而是ArrayDeque。

不多说,再看性能测试对比。对ArrayDeque和LinkedList分别做1000000次以下操作,统计执行时间(ms):

头部插入尾部插入遍历
ArrayList121266
LinkedList6115310

可以看出,ArrayDeque在每项时间指标都优于LinkedList。另外在空间上,ArrayDeque底层使用的循环数组也是优于LinkedList使用的Node链表。

结论:无论在时间还是空间上,ArrayDeque都优于LinkedList。

顺便说一句,JDK中还提供了Stack类。虽然它名字就叫Stack,一般不会用到它实现栈,甚至Java官方都建议不要使用它。因为有以下缺陷:

  1. 继承关系和方法设计混乱。
  2. 为了线程安全所有方法加线程锁,性能较差。

那么综合看来,LinkedList是否一无是处呢?我觉得它的存在还是有一定价值的:

  1. 典型的数据结构。作为一种基础数据结构,链表在几乎每种语言中都有自己的实现。LinkedList作为链表在Java中的实现,起到了教学和理论研究的作用。它在Java中性能不好更多与JVM本身的内存结构有关,并非在所有语言中都是这样。
  2. 历史原因。LinkedList刚出来时还是实现Queue和Stack的最佳选择,不过后面1.6版本推出的ArrayDeque在性能上后来居上,为了版本兼容的考虑LinkedList还是保留了下来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48292.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

猿如意开发工具|JetBrains GoLand

一、猿如意是什么? 是CSDN推出的桌面客户端,旨在为广大开发者提供效率工具、文档、代码等优质工具和内容,提升开发者的学习和工作效率,详情点击👉【猿如意官网】。为了让更多开发者更好的认识、了解、使用猿如意中的每…

项目管理(如何进行项目质量管理)

需要进行的工作: 1、规划项目质量管理:识别项目及其可交付成果的质量要求和/或标准,并书面描述项目将如何证明 符合质量要求和/或标准的过程。 2、管理质量:管理质量是把组织的质量政策用于项目,并将质量管理计划转化…

蓝桥杯嵌入式cubeMX自动生成的gpio.c文件解析

文章目录前言一、如何生成gpio.c文件二、gpio.c内部实现总结前言 这篇文章将带大家了解一下cubeMX自动生成的gpio.c文件。 一、如何生成gpio.c文件 在LED这篇文章中我们配置了控制LED的GPIO引脚,选择了PD2和PC8 PC9这三个引脚,并且将他们都设置为了输…

数图互通高校房产管理系统——住房管理

1、住房管理 1.1 住房档案 住房模块的管理主要是针对学校的承租住宅和已售住宅的管理,用于登记已售住宅的产权人信息,记录承租住宅的租赁起止日期、月租金等基本信息。 支持住房的坐落信息、楼栋、房间信息的维护。坐落位置主要维护校区编号、校区名称…

说明白正反向代理,以及Nginx和Gunicorn

一:什么是Nginx Nginx的产生 没有听过Nginx?那么一定听过它的"同行"Apache吧!Nginx同Apache一样都是一种WEB服务器。基于REST架构风格,以统一资源描述符(Uniform Resources Identifier)URI或者统一资源定位符(Uniform …

图像质量评价指标metrics:PSNR 、SSIM、LPIPS

一、PSNR(峰值信噪比) 1.定义 是基于对应像素点间的误差,即基于误差敏感的图像质量评价,由于并未考虑到人眼的视觉特性(人眼对空间频率较低的对比差异敏感度较高,人眼对亮度对比差异的敏感度较色度高&…

HTTP协议中的Cookie 和 Session

Cookie Session一 Cookie1.Cookie是什么?2.Cookie的工作机制二 Session1.Session的工作机制三 Cookie 和 Session 的区别一 Cookie 1.Cookie是什么? Cookie是一组键值对保存在客户端,服务器给浏览器的一组键值对(Sessionidxxxxxxx)通过Cookie来传递给客户端&…

比搞笑诺奖还离谱,看完国产AIGC最新创作,把我给整不会了

杨净 萧箫 发自 凹非寺量子位 | 公众号 QbitAI现在,AI生成的东西,“真实”得都让我有点害怕了——只是给出《马斯克获得诺贝尔物理学奖》这个标题,AI竟然就刷刷刷几下,蹦出了一整套大纲来?!如果让AI生成一些…

5G WiFi 安信可 BW16 模组 RTL8720DN 入门笔记 2:Linux 搭建二次开发SDK开发环境,点亮一盏LED灯。

首先按照环境所依赖的包: sudo apt-get install git wget libc6-i386 lib32ncurses5 make bc gawk ncurses-dev 开始获取SDK源码,并且修改权限: git clone https://github.com/ambiot/ambd_sdk.git sudo chmod -R 777 ambd_sdk然后开始编译…

傻白入门芯片设计,三大基本定律(十)

1.摩尔定律(Moores Law):集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍。换言之,处理器的性能大约每两年翻一倍,同时价格下降为之前的一半。。 2.登纳德缩放定律(Dennard Scalin…

一些跨平台技术方案的经验参考

今天就站在一个小开发的视角分享一下一个小项目是如何进行跨平台方案选型的 本系列文章先站在公司的的角度对产品技术选型进行分析,然后再根据我们项目实际开发经验进行汇总,供大家参考。 目前大前端技术也非常丰富,可以实现,一…

Shader中需要数学知识

在Shader的学习中,我们可能需要一些数学知识,我也是学习了一段时间,之前数学的知识都忘了,重新来一遍吧,我把学习的点分享一下。 向量: 点乘: 向量A向量B A向量的模 * B向量的模 * cosθ 一般…

深度学习与总结JVM专辑(五):类加载机制

类加载机制前言什么是类加载机制类的生命周期类的加载:查找并加载类的二进制数据链接验证:确保被加载的类的正确性验证?有必要吗准备:为类的静态变量分配内存,并将其初始化为默认值解析:把类中的符号引用转…

ZooKeeper 避坑实践:如何调优 jute.maxbuffer

作者:子葵 背景 在日常运维 ZooKeeper 中,经常会遇到长时间无法选主,恢复时进程启动又退出,进而导致内存暴涨,CPU飙升,GC频繁,影响业务可用性,这些问题有可能和 jute.maxbuffer 的…

Kotlin高仿微信-第17篇-单聊-转账

Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。 Kotlin高仿…

深度学习基础知识回顾

1. Dataset调用了什么接口? 回答应该是__len__方法和__getitem__方法。 之前写过一篇关于Dataset和Dataloader的介绍: http://t.csdn.cn/b4x0hhttp://t.csdn.cn/b4x0h 2. 目标检测里面用了哪些损失函数? 我的回答是Focal Lo…

【Linux】权限讲解

一、什么是权限 1、权限概念 权限随处可见,在生活中,腾讯非VIP用户不能观看VIP视频,看小说也需要会员,所以权限是限制人的,一件事是否允许被谁做。在Linux系统中也有许多权限,访问文件需要权限&#xff0c…

Kafka: Windows环境-单机部署和伪集群、集群部署

1. kafka 单机版部署 1.1 zookeeper 安装 (1)下载安装包 官网:Apache ZooKeeper 我用的是 apache-zookeeper-3.7.1-bin.tar.gz 注意:zookeeper的安装路径不要有中文,建议也不要有空格,比如Program Files这样的路径…

移动跨平台技术方案浅析

随着互联网产品逐渐兴起,越来越多产品体验从线下搬到了线上,尤其是移动互联网产品相关,所以很多企业就会更加重视降本增效,以最快的速度推出质量满意度高、用户体验性好的产品,那么就顺势催生了很多跨端跨平台方案。 …

并发编程九 线程池Executor框架

一 线程 线程是调度CPU资源的最小单位,线程模型分为KLT模型与ULT模型,JVM使用的KLT模型; Java线程与OS线程保持1:1的映射关系,也就是说有一个java线程也会在操作系统里有一个对应的线程。Java线程有多种生命状态 NEW,新建 RUNN…