• ArrayList 和 LinkedList 之间应该怎么选择


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

    相信很多人在面试时都被问过这个问题,然后一般回答: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还是保留了下来。
  • 相关阅读:
    自然语言处理(NLP)技术
    2024年火爆全网的三款ai智能直播系统,你知道哪一种?
    HarmonyOS应用开发-组件状态管理
    声声入耳:音频新体验
    【SQL】SQL可能是你掌握的最有用的技能
    windows优化原神
    Java面试——专业技能
    Windows下Eclipse C/C++开发环境配置教程
    Linux下使用Git入门
    第06章 MyBatisPlus概述
  • 原文地址:https://blog.csdn.net/needmorecode/article/details/128091988