LinkedList 落幕了吗?作者自己都不用

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 近期,看到网上有小伙伴们在讨论 LinkedList 作者自己都不用 LinkedList,我特意从网上搜索了一下,结果真让我找到了。

image.png


hi 大家好,我是 DHL。公众号:ByteCode ,专注分享最新技术原创文章,涉及 Kotlin、Jetpack、算法动画、数据结构 、系统源码、 LeetCode / 剑指 Offer / 多线程 / 国内外大厂算法题 等等。


近期,看到网上有小伙伴们在讨论 LinkedList 作者自己都不用 LinkedList,我特意从网上搜索了一下,结果真让我找到了。


twitter.com/joshbloch/s…


image.png


大神真的不用 LinkedList 了吗? 我仔细扒了一下,如下图所示,大神的回复。


image.png


其实大神非常喜欢链表的数据结构,在 C 语言中是非常有用的。并且也非常认可 ArrayDeque 的实现,因为 ArrayDeque 作为栈使用时可能比 Stack 快,作为队列使用时可能比 LinkedList 快。


但是为什么不用 LinkedList 呢?LinkedList 基于双向链表实现的双端队列,链表 和 队列都是非常好的数据结构,但是 Java 中 LinkedList 存在性能问题,所以在实际项目中,很少会用到,先来一起了解一下 LinkedList 的特点。


LinkedList 特点



  • LinkedList 是基于双向链表的结构来存储元素,所以长度没有限制,因此不存在扩容机制
  • 由于链表的内存地址是非连续的,所以只能从头部或者尾部查找元素,查询的时间复杂为 O(n),但是 JDK 对 LinkedList 做了查找优化,当我们查找某个元素时,若 index < (size / 2),则从 head 往后查找,否则从 tail 开始往前查找 , 但是我们在计算时间复杂度的时候,常数项可以省略,故时间复杂度 O(n)


Node<E> node(int index) {
    // size >> 1 等价于 size / 2
    if (index < (size >> 1)) {
        // form head to tail
    } else {
        // form tail to head
    }
}


  • 链表通过指针去访问各个元素,所以插入、删除元素只需要更改指针指向即可,因此插入、删除的时间复杂度 O(1)
  • 它是非线程安全的集合


LinkedList 属于链式队列,与之相对应的 ArrayDeque 是基于数组实现的双端队列,ArrayDequeLinkedList 数据结构的特点如下所示。


集合类型 数据结构 初始化及扩容 插入/删除时间复杂度 查询时间复杂度 是否是线程安全
ArrayDeque 循环数组 初始化:16
扩容:2 倍
0(n) 0(1)
LinkedList 双向链表 0(1) 0(n)


更多关于 ArrayDequeLinkedList 的优缺点,在什么情况下使用,以及它们谁更快,请前往查看 图解 ArrayDeque 比 LinkedList 快


了解完数据结构特点之后,接下来我们从两个方面分析为什么 LinkedList 存在性能问题。


LinkedList 存在的性能问题



  • 从速度的角度:ArrayDeque 基于数组实现双端队列,而 LinkedList 基于双向链表实现双端队列,数组采用连续的内存地址空间,通过下标索引访问,链表是非连续的内存地址空间,通过指针访问,所以在寻址方面数组的效率高于链表。
  • 从内存的角度:虽然 LinkedList 没有扩容的问题,但是插入元素的时候,需要创建一个 Node 对象, 换句话说每次都要执行 new 操作,当执行 new 操作的时候,其过程是非常慢的,会经历两个过程:类加载过程 、对象创建过程。
  • 类加载过程
  • 会先判断这个类是否已经初始化,如果没有初始化,会执行类的加载过程
  • 类的加载过程:加载、验证、准备、解析、初始化等等阶段,之后会执行 <clinit>() 方法,初始化静态变量,执行静态代码块等等
  • 对象创建过程
  • 如果类已经初始化了,直接执行对象的创建过程
  • 对象的创建过程:在堆内存中开辟一块空间,给开辟空间分配一个地址,之后执行初始化,会执行 <init>() 方法,初始化普通变量,调用普通代码块


在上一篇文章 图解 ArrayDeque 比 LinkedList 快速度内存 两个方面分析了  ArrayDeque 的性能都比 LinkedList 要好,并结合实际的案例来验证,结果如下图所示。


image.png


在之前的文章中,我围绕着 LinkedList (栈、队列 等等)写了四篇文章,从不同的角度进行了分析。


  • 栈的定义
  • 栈的实现
  • 为什么不推荐使用 Java 栈
  • 性能低
  • 破坏了原有的数据结构
  • 不推荐使用了,为什么现在还在用
  • 为什么推荐使用 Deque 接口替换栈
  • 效率比 Java 栈快
  • 屏蔽掉无关的方法
  • Stack 和 ArrayDeque 区别
  • 栈的时间复杂度
  • 栈的实战
  • 为什么不推荐使用 Java 栈
  • JDK 推荐使用 ArrayDeque 代替 Stack 真的合理吗
  • 大神不推荐使用 ArrayDeque 代替 Stack
  • 如何实现一个真正意义上的栈
  • ArrayDequeLinkedList 数据结构的特点?
  • 为什么 ArrayDequeLinkedList 快?
  • 主要来学习如何设计循环队列
  • JDK 源码是如何设计队列?
  • 队列的大小为什么要设置成 2 的整数次幂?
  • 位运算 效率比 非位运算 快多少?
  • ArrayDeque 的 2 的整数次幂计算逻辑和 HashMap 有什么区别?
  • 自己如何设计一个循环队列?


如果有帮助 点个赞 就是对我最大的鼓励


代码不止,文章不停


欢迎关注公众号:ByteCode,持续分享最新的技术


最后推荐长期更新和维护的项目:


  • 个人博客,将所有文章进行分类,欢迎前去查看 hi-dhl.com
  • KtKit 小巧而实用,用 Kotlin 语言编写的工具库,欢迎前去查看 KtKit
  • 计划建立一个最全、最新的 AndroidX Jetpack 相关组件的实战项目 以及 相关组件原理分析文章,正在逐渐增加 Jetpack 新成员,仓库持续更新,欢迎前去查看 AndroidX-Jetpack-Practice
  • LeetCode / 剑指 offer / 国内外大厂面试题 / 多线程 题解,语言 Java 和 kotlin,包含多种解法、解题思路、时间复杂度、空间复杂度分析


image.png



近期必读热门文章




目录
相关文章
|
算法 Java 测试技术
【备战蓝桥杯 | 软件Java大学B组】十三届真题深刨详解(2)
【备战蓝桥杯 | 软件Java大学B组】十三届真题深刨详解(2)
70 0
|
3月前
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
29 1
|
7月前
杨老师带你深入研究ArrayList和LinkedList的区别不同
杨老师带你深入研究ArrayList和LinkedList的区别不同
44 0
|
7月前
|
存储 Java 索引
杨老师课堂之ArrayList集合解析
杨老师课堂之ArrayList集合解析
34 0
|
存储 人工智能 Java
【备战蓝桥杯 | 软件Java大学B组】十三届真题深刨详解(1)
【备战蓝桥杯 | 软件Java大学B组】十三届真题深刨详解(1)
520 0
代码随想录算法训练营 | 数组小结
代码随想录算法训练营 | 数组小结
|
Java
代码随想录训练营第十二天 | 栈与队列
代码随想录训练营第十二天 | 栈与队列
89 0
|
算法
代码随想录算法训练营第四天 | 链表 + 每日一题
代码随想录算法训练营第四天 | 链表 + 每日一题
119 0
《给ITer的技术实战进阶课-阿里CIO学院独家教材(四)》电子版地址
给ITer的技术实战进阶课-阿里CIO学院独家教材(四)
92 0
《给ITer的技术实战进阶课-阿里CIO学院独家教材(四)》电子版地址
|
Java C++ Python
蓝桥杯官网 试题 PREV-278 历届真题 双向排序【第十二届】【省赛】【研究生组】【C++】【C】【Java】【Python】四种解法
蓝桥杯官网 试题 PREV-278 历届真题 双向排序【第十二届】【省赛】【研究生组】【C++】【C】【Java】【Python】四种解法
290 0
蓝桥杯官网 试题 PREV-278 历届真题 双向排序【第十二届】【省赛】【研究生组】【C++】【C】【Java】【Python】四种解法

热门文章

最新文章

下一篇
开通oss服务