JAVA源码学习-LinkedList

VS2022如何兼容老项目?.NET Framework 4.0/4.5安装避坑指南 本文提供了在Visual Studio 2022中兼容和维护.NET Framework 4.0/4.5等老旧项目的完整解决方案。针对VS2022无法直接识别旧框架的核心问题,文章详细剖析了原因,并重点推荐通过官方NuGet包安全获取引用程序集的方法,给出了从下载、解压到部署至标准目录的详细步骤。同时,文章还深入探讨了项目文件格式过旧、NuGet包还原失败等进阶问题的排查与解决策略,旨在帮助开发者高效、稳定地在现代开发环境中维护历史代码库。 阅读详情

很多公司的面试题都会问到ArrayList和LinkedList的区别,在这里我先稍微做下总结。他们都是List的实现类,实现方式上ArrayList是用数组,LinkedList是用双向链表,性能上ArrayList随机访问效率高,但插入和删除效率低,而LinkedList随机访问效率低,但插入和删除效率高,这样的性能又决定了他们的使用场景不同。那么是什么导致这哥俩性能那么互补呢?希望这篇对LinkedList的源码解读能提供这个问题的答案。

       按惯例先上LinkedList类的定义:

  public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
      跟ArrayList继承自AbstractList不同,LinkedList继承自AbstractSequentiaList,与ArrayList一样都实现了List,Cloneable和Serializable接口,都可以克隆并序列化,不一样的是实现了Deque接口,这个接口定义了跟双端队列相关的操作。

      LinkedList通过链表实现,那么肯定以一个链表节点作为基础数据单元,跟ArrayList的数组不一样,这个链表节点的定义如下:

   private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

      每个节点都保存了存储的元素,前一个节点,后一个节点,即只能看到跟自己相邻的节点。

LinkedList之中定义了三个属性:

    transient int size = 0;

    /**
     * Pointer to first node.
     * Invariant: (first == null && last == null) ||
     *            (first.prev == null && first.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */
    transient Node<E> last;
size属性记录了LinkedList中存储的元素个数,first和last分别是LinkedList的头节点和尾节点。


LinkedList的构造方法有两个

   /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }

    /**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param  c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

ArrayList中的无参构造方法(默认构造函数)还默认初始化一个长度为10的数组,LinkedList中的无参构造方法啥也没有,这该如何理解?从这里看,用无参构造函数初始化的时候貌似什么也没做,其实不然,仔细看上面提到的Node类,它通过静态加载方式声明,即在工程加载时变初始化了Node类,并包含了节点,前驱,后继三个属性;在初始化LinkedList时,又将这三个属性赋给first和last,并且都为null,即得到了一个空链表。构建对象较完整的顺序是:

先在工程加载时初始化静态代码(Node类),new LinkedList()时,先执行父类的非静态代码初始化父类成员变量,然后执行父类构造方法,接着执行子类成员变量,最后才执行子类构造方法,继而完成了对象的创建。

        带参数的构造方法里有一个addAll(Collection), 即将Collection转换为LinkedList所能接受的数据(节点),将这些节点追加到linkedList中。

addAll(int, Collection),重载addAll(Collection),在指定位置插入Collection到linkedList中

    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
    public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);//如果index小于0且大于size,则抛出IndexOutOfBoundsException异常。

        Object[] a = c.toArray();//将Collection转换为对象数组
        int numNew = a.length;
        if (numNew == 0)//如果待插入对象为空,则直接返回。这里为什么不直接使用a!=null?原因我的理解是执行效率问题和不容易出错
            return false;

        Node<E> pred, succ;//根据index查找对应节点信息,以确定Collection的始末位置。pred为起始位置,succ为结尾位置,可将其看作两个指针。
        if (index == size) {//如果index==size,即在链表末尾添加元素,则Collection的起始位置为链表的last,结尾位置为null
            succ = null;
            pred = last;
        } else {//否则,结尾位置为index对应的那个节点succ,起始位置为succ的前驱节点。
            succ = node(index);
            pred = succ.prev;
        }

        for (Object o : a) {//对Collection中每一个元素创建节点newNode,使其前驱为pred,后继null
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);
            if (pred == null)//如果pred==null,则说明为第一个元素,first指向newNode
                first = newNode;
            else             //否则,起始位置pred的后继节点为newNode
                pred.next = newNode;
            pred = newNode;,//变更新的起始位置为newNode
        }//该for循环执行之后会将确定好的起始位置的节点,Collection中每个元素创建的节点连接起来,此时pred存放着所有Collection添加完成后的末尾位置

        if (succ == null) {//如果结尾位置(即index对应的那个节点)为null,说明是在链表结尾添加,则将last指针指向succ的前置
            last = pred;
        } else {           //否则将所有Collection添加完成后的末尾位置pred的后继指向index对应的节点,index节点的前驱指向pred
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;//链表长度增加Collection的长度
        modCount++;
        return true;
    }
构造方法调用的addAll最终会将size作为index参数调用addAll(int index, Collection<? extends E> c),怎么实现的等看懂了以后再写。

接下来就是几个比较重要的私有方法,LinkedList的大多数公有方法里都会出现他们的身影。


linkFirst(E e),将e插入为第一个元素

    /**
     * Links e as first element.
     */
    private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
    }

这里我将first,last理解为C语言里的指针,将first指向的元素复制给Node f,声明一个newNode节点,使其前驱为null,节点元素为e,后继为f(此时的f为原来链表里第一个元素),此时已经完成了头结点->newNode->f的链接,在将first的指针位置更新到newNode,是newNode成为链表第一个元素。如果链表第一个元素为null,即空链表,则将last也指向newNode;否则,使f的前驱指向newNode,建立从f-》newNode的链接。同时将LinkedList的size加一。


linkLast(E e),将e插入为最后一个元素

    /**
     * Links e as last element.
     */
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

过程跟linkFirst类似。先将LinkedList最后一个元素拷贝至l,初始化一个newNode使其前驱为l,元素为e,后继为null,此时完成从newNode->l的链接;更新last指针为newNode;如果原LinkedList最后一个节点为null(即为空链表),将first也指向newNode;否则,将原最后一个节点的后继指向newNode,完成l->newNode的链接,同时将LinkedList的size加一。


linkBefore(E e, Node<E> succ),插入一个元素到succ之前,如果succ的前置为null(即succ为第一个节点),则同linkFirst方法。

    /**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        final Node<E> pred = succ.prev;
        final Node<E> newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

流程是:先将succ的前驱元素复制给pred,初始化newNode节点使其前驱为pred,元素为e,后继为succ,此时建立了从newNode->succ的前置元素pred,newNode到succ的链接;建立succ->newNode的链接;如果succ的前置元素为null,则令newNode为一个元素;否则令succ前置元素的后继指向newNode,建立pred->newNode的链接,同时将LinkedList的size加一。

为什么没有类似linkAfter的方法,个人理解这跟linkBefore功能上重合,ORACLE的程序猿们懒得写~偷笑

以上linkFirst,linkLast,linkBefore可视作LinkedList的插入方法,过程总结如下:

先找出待插入位置的元素,另存副本A;新建node节点B与A链接,并调整收尾指针first和last,最后size加1。按照这个思路在比较这三个方法,发现linkFirst对应了linkBefore的一种特殊情况,即linkBefore的succ元素的前驱为null,即succ为链表第一个元素。


接下来我们看一组unlink方法,unlink方法顾名思义就是将LinkedList中的某个元素移除,一般思路是先将这个元素的左右链接断开,然后将这个元素的前驱后继元素链接上。

unlinkFirst(Node<E> f)

    /**
     * Unlinks non-null first node f.
     */
    private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }

既然是移除linkedList的第一个元素,那么这个方法在供其他方法使用的时候,f肯定会是first指针指向的元素。

备份第一个元素f的item和后继元素,然后将f的item和后继指针指向空,即从该链表中断开链接。将first指针指向原有链表第二个元素,即f的后继。如果f的后继也为null,那说明移除后成了空链表,尾指针last也指向null,否则将f的后继元素的前驱指向null,同时size减一,返回删除节点的元素值。


unlinkLast(Node<E> l)

    /**
     * Unlinks non-null last node l.
     */
    private E unlinkLast(Node<E> l) {
        // assert l == last && l != null;
        final E element = l.item;
        final Node<E> prev = l.prev;
        l.item = null;
        l.prev = null; // help GC
        last = prev;
        if (prev == null)
            first = null;
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }

类似的,unlinkLast的入参l肯定会是last指向的尾节点

备份尾节点的元素值及其前驱节点,然后将l的item和前驱指针指向空,让此节点从LinkedList中断开,将last指向l的前驱节点。如果前驱节点为空,说明移除后成了空链表,则让first也指向null,否则l前置节点的后继指向空,同时将size减一。


unlink(Node<E> x):删除LinkedList中任意非空节点x

    /**
     * Unlinks non-null node x.
     */
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
    }
先备份x的元素值,前驱节点和后继节点;如果x的前驱为null(即x为链表第一个节点),则让first指向x的后继节点,否则x前驱节点的后继指向x的后继节点,并将x的前驱断开;如果x的后继节点为null(即x为链表最后一个元素),则让last指向x的前驱节点,否则x的后继节点的前驱指向x的前驱节点,并将x的后继断开;同时将x的元素值置空,size减一并返回移除的节点元素值。

从上面的插入删除方法可以看到,链表的插入删除操作是比ArrayList效率要高的。那为什么链表的查找效率比ArrayList低,那是因为ArrayList支持随机访问而链表不能,那链表是如何查找的呢?看下面的方法:

node(int index)

    /**
     * Returns the (non-null) Node at the specified element index.
     */
    Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

根据提供的元素序号index,使用二分法在链表中循环遍历对应的元素,因为链表是无序集合,只能按照每个节点的后继去挨个查找。就是说每次对LinkedList做查找,排除最好的情况,LinkedList都得或多或少把自个元素挨个点个到,这种查找方式由链表的特性决定,实属无奈之举,所以效率没ArrayList高。


理解了上面几个方法,那么下面的方法就容易多了,无非是对以上方法的封装,增加一些校验而已,这里就简写了。

getFirst(),getLast():返回链表第一个元素值和最后一个元素值,不是节点。

removeFirst(),removeLast():分别调用unlinkFirst和unlinkLast移除第一个和最后一个节点,返回节点值。

addFirst(E),addLast(E):分别调用linkFirst和linkLast增加第一个节点和最后一个节点,返回节点值。

contains(Object o):分别调用indexOf(o)对LinkedList进行遍历查找对应的元素o,没有用到node(int index)方法。

add(E):调用linkFirst第一个节点,返回true。

remove(Object):遍历LinkedList,找到Object对应的节点,使用unlink方法移除,移除成功返回true,没有该元素则返回false。

等等,分别实现由List的增删查方法,队列的增删查方法和双端队列的增删查方法,太多了,这里不一一列举了。



工业缺陷检测深度学习方法综述 异常:点异常、 上下文异常和集群异常。点异常:又称为离群值 (outliers)[9], 描述数值上偏离正 常样本的独立数据。与异常相近的概念还包括新颖点(novelty)和分布外数据。上下文异常:同样描述数据点,其数值属于正常范围,但不符合局部上下文规律。集群异常:描述一系列相关数据的集合,集合中的每一个实例的数值在单独考察时都处于正常值域,但集 合整体的相关性特征不服从正常模式。一般的图像异常检测往往仅需区分正常与异常样本,而工业缺陷检测更关注于检测 图像中的异常像素. 阅读详情

相关推荐

手把手教你用示波器抓取MIPI D-PHY波形:从LP11到HS Burst的完整信号解析

本文详细介绍了使用示波器精准捕获MIPI D-PHY信号的关键技巧,包括探头选择、示波器参数设置、信号状态解析及高级触发配置。通过实战案例和波形分析,帮助工程师快速识别从LP11到HS Burst的各种信号状态,解决常见的信号完整性问题,提升调试效率。

weixin_30471561的博客 563

java中ArrayList和LinkedList使用注意事项

1. ArrayList和LinkedList的访问方式 由于ArrayList实现了RandomAccess访问方式所以在循环读取的时候我们采用下标的方式访问。 如果我们使用foreach方式访问(即:伪码) for(Object obj : ArrayList){ System.out.println(obj); } 以上访问方式会采用Iterator的方式访问。Iterator采

u012418131的博客 1389

绕过ROS2!在RDK X5上直接用Python调用海康相机C++ SDK的避坑指南

本文详细介绍了在RDK X5上绕过ROS2,直接使用Python调用海康相机C++ SDK的轻量化方案。通过Cython构建Python绑定,提取海康相机SDK核心组件,实现高效图像采集。文章涵盖环境准备、Cython接口设计、编译系统配置及性能优化技巧,特别适合ARM64平台开发者。

weixin_33712987的博客 250

20. “我”模块(二)之星座

上一节对欢迎模块进行了综述(可参见 “我”模块(一) 进行了解),接下来将从“我”模块(二)开始详细介绍: [“我”模块(二)之日历] [“我”模块(二)之星座] [“我”模块(二)之星座选择] [“我”模块(二)之涂鸦] [“我”模块(二)之地图] 知识点 掌握“日历”界面的开发,使用日历展示当前年份 掌握“星座”界面的开发,选择不同的星座展示不同...

Jennyni1122的博客 519

RabbitMq安装

本文详细介绍了在CentOS7系统上离线部署RabbitMQ4.3.2的完整流程。主要内容包括:1)准备RabbitMQ安装包、Erlang依赖和socat网络工具;2)安装系统编译依赖并编译安装Erlang;3)部署RabbitMQ服务,配置环境变量和socat依赖;4)启用Web管理插件并创建管理员账号;5)配置防火墙放行端口;6)设置Systemd开机自启服务;7)提供常用运维命令。文档特别强调离线部署注意事项,包括socat依赖、版本兼容性、账号安全及主机名配置等问题,为生产环境部署提供完整解决方案

sinat_25821779的博客 323

7、布尔网络的基础定义

本文介绍了布尔网络的基础定义及其在系统生物学中的应用。布尔网络是一种描述复杂系统动态行为的数学模型,由布尔变量和布尔函数组成,能够模拟生物系统中基因调控、信号传导和细胞代谢等过程。文章详细阐述了布尔网络的基本结构、动力学特征(如状态转移图和吸引子),以及其在生物建模中的重要价值,并探讨了优化和简化技术(如Backward Boolean Equivalence)如何提升其计算效率。

yhn45678901的博客 264

Java中LinkedList源码学习

简介 内部结构分析 核心方法 LinkedList源码分析 构造方法 添加(add)方法 根据位置取数据的方法 根据对象得到索引的方法 检查链表是否包含某对象的方法: 删除(remove/pop)方法 简介 LinkedList是一个实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性; LinkedList不是线程安全的,如果想使LinkedList变成线程安全的..

weixin_41590779的博客 429

ARM交叉编译gdbserver并远程在线调试

arm-linux平台。5、生成完整的makefile,新建full_install,执行 ./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- CC=arm-linux-gnueabihf-gcc --prefix=/home/geyuxi/Documents/full_install。如果--host和--build不同,是交叉编译;

wangjie36的博客 3169

java基础之LinkedList源码学习

LinkedList源码解读: 特点说明: LinkedLIst是一个实现了List接口和Deque接口的双端链表; LinkedList底层的链表结构使它支持高效的插入和删除操作,另外它实现了Deque接口,使得LinkedList类也具有队列的特性; LinkedList不是线程安全的,如果想使LinkedList变成线程安全的,可以调用静态类Collections类中的sychronizedList方法: List list=Collections.synchronizedList(new Lin

T_ZZZ的博客 323

信号处理算法:离散余弦变换(DCT)_(1).离散余弦变换(DCT)概述

离散余弦变换的数学定义如下:对于一个长度为NNN的离散信号xnx(n)xn,其DCT变换后的系数XkX(k)XkXk∑n0N−1xncos⁡πNn12kk012N−1Xkn0∑N−1​xncosNπ​n21​kk012N−1其中,kkk是频率指数,nnn是时间或空间索引。离散余弦变换(DCT)是一种强大的信号处理技术,广泛应用于图像压缩、音频处理、数据压缩等领域。

2401_87715305的博客 1554

通用抓取算法AnyGrasp(Graspnet)——本地部署并测试自定义输入数据

背景:GraspNet在数据采集方面,首先将相机固定到机械臂末端,对同一个场景拍摄256个不同的角度,同时场景中的每个物体都会提前采集好3D模型,之后将其投射到仿真环境中,在仿真环境中,对抓取位姿进行打标签,如此完成数据的采集。在运行官方的测试示例时,使用的是路径下的输入数据,可以分析下。color.png(输入):rgb图像(输出):输出的生成抓取位姿的图像depth.png(输入):和当前rgb图像对应的深度图像(保存格式是单通道uint16)meta.mat。

boss-dog 1330

java源码学习-LinkedList

这里写目录标题一级目录二级目录三级目录 一级目录 二级目录 三级目录

星光之子的博客 235

C#的GDI+绘图详解

/消除锯齿 或 AntiAlias。// 1.在窗体或控件的Paint事件中,用PaintEventArgs e 创建绘图对象 ---- 控件或窗体重绘时。//为控件创建绘图对象。//--------------------以上方法三选一。//2.创建绘图对象 panel1中绘图。

weixin_50920631的博客 3457

java集合 LinkedList原理, 通过源码学习进行深入了解

LinkedList 基于源码学习概述继承关系成员变量内部节点类构造函数成员方法内部工具类方法linkFirst、linkLast、linkBefore 方法unlinkFirst、unlinkLast、unlink 方法node方法检查索引合法性的方法Deque相关方法单向队列方法栈的方法双端队列方法List相关方法add方法addAll方法get方法set方法remove方法size方法contain方法clear方法clone方法toArray方法LinkedList 小结ArrayList 和 Li

qq_30921153的博客 796

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【Java学习003】Java-LinkedList源码解析

详细介绍LinkedList源码

pcx171的博客 212

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java小白集合源码的学习系列:LinkedList

目录 LinkedList 源码学习 LinkedList继承体系 LinkedList核心源码 Deque相关操作 总结 LinkedList 源码学习 前文传送门:Java小白集合源码的学习系列:ArrayList 本篇为集合源码学习系列的LinkedList学习部分,如有叙述不当之处,还望评论区批评指...

java梦工厂 196

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java集合基础:LinkedList详解及源码学习

内部结构分析 简介 内部结构分析 LinkedList源码分析 构造方法 添加(add)方法 根据位置取数据的方法 根据对象得到索引的方法 检查链表是否包含某对象的方法: 删除(remove/pop)方法 LinkedList类常用方法测试: 简介 LinkedList是一个实现了List接口和Deque接口的双端链表。 LinkedList底层的链表结构使它支持高效的插入和删除操作...

Java Punk 692

深入学习Java集合类源码之LinkedList

一.简介: LinkedList是一种可以在任何位置进行高效地插入和移除操作的有序序列,它是基于 双向链表 实现的。 LinkedList可以被当作堆栈、队列或双端队列进行操作。 LinkedList 是非同步的 二.源码分析: 1.继承关系 public class LinkedList<E> extends AbstractSequentialList<E&gt...

atomatom98的博客 232

java容器源码学习02: LinkedList

文章目录接口和实现类分析:源码分析总结 接口和实现类分析: public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable 1、List接口:列表,add、set、等一些对列表进行操作的方法 2、Deque接口:有队列的各种特性, 3、Cloneable接口:能

weixin_43874468的博客 130

Java集合学习(三)LinkedList源码学习

Java集合学习(三)LinkedList源码学习 前言 侵删,学习记录笔记。 有错请指正 LinkedList 集合List的实现类。与ArrayList不同的是,LinkedList采用链表结构实现,插入和删除性能较好,但查询速度较慢。LinkedList实现了Deque<E>接口,可以当作双向队列来使用,亦或是栈,堆。 结点 这是LinkedList的一个静态内部类,链表实现的关键,通过结点类可以将每个结点对象连接起来。 private static class Node<E&g

Zyd_code的博客 259

【深入学习java集合框架】LinkedList源码学习

1、LinkedList底层通过双向链表实现,双向链表的每个节点用内部类Node表示。 2、LinkedList通过first和last引用分别指向链表的第一个和最后一个元素,当链表为空的时候first和last都指向null。 3、LinkedList的实现方式决定了所有跟下标相关的操作都是线性时间,而在首段或者末尾删除元素只需要常数时间。 4、LinkedList没有实现同步(synch

Wanna的博客 1082

java源码学习,linkedlist中transient修饰变量

首先需要了解下序列化和非序列化,Java序列化是指将Java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存Java对象状态的过程。如果writeObject使用某种规则序列化,则相应的readObject需要相反的规则反序列化,以便能正确反序列化出对象。而transient修饰的变量和静态变量不会被序列化,使用transient修饰的属性,java序列化时,会忽略掉此类字段。对于引用类型,值是null;这样避免了链接节点的失效,因为经过序列化、反序列化后节点的内存地址时不同的(一般来说)。

weixin_37703358的博客 440

Java集合学习:LinkedList源码详解

链表不需要指定容量,只要内存够大,就可以一直存储下去。链表存储时,分配完内存空间后,只需要将引用进行关联就可以,比起ArrayList可能会造成空间移动,效率高得多。但是在存储时,我们看到它是采用遍历的方式,进行下标查询,随便使用了二分进行切割,但在数据量大的情况下自旋时间长,对CPU的消耗比较大。

猪大肠的博客 542

基于源码的Java集合框架学习③ LinkedList

类 LinkedList&lt;E&gt; List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列 (deque)。 此类实现 Queue 接口,为 add、poll 等提...

lazyRabbit的博客 210

JAVA-LinkedList 源码学习-201805

JAVA-LinkedList 源码学习-201805(jdk 8 源码)一、概念  List 接口的链表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。其大小理论上只受内存大小影响。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。    ...

ever_who的博客 330

【Java8-集合源码学习3-CopyOnWriteArrayList、LinkedList源码学习】

java8集合源码学习

打怪升级 548
上一篇: JAVA源码学习-ArrayList
下一篇: JAVA源码学习-HashMap
二农
博客等级 码龄17年 23粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值