源码分析LinkedList底层实现

这篇博客详细解析了LinkedList在Java中的实现原理,包括其内部双向链表的结构和add、remove方法的执行流程。在add操作中,通过linkLast方法实现了节点的插入,而在remove方法中,通过unlinkFirst方法删除指定节点,使节点从链表中彻底移除。这些深入的源码分析有助于更好地理解和使用LinkedList。
摘要由CSDN通过智能技术生成

LinkedList特点

  • LinkedList和ArrayList一样,它们都是非线程安全的;并且都允许存放null值;
  • LinkedList的底层是一个双向链表;所以它在进行插入、删除效率较高,而做查询操作效率较低;
  • 它是一个链表,所以不存在容量不足的问题,因此没有扩容机制。

LinkedList的内部

在这里插入图片描述

可以发现,LinkedList的无参构造器中不执行任何操作。

其内部类Node

private static class Node<E> {
    E item;	//	节点中的数据项
    Node<E> next;	// 当前节点的next指针,指向下一个节点对象
    Node<E> prev;	// 当前节点的prev指针,指向上一个节点对象

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

在这里插入图片描述

分析LinkedList源码查看add操作到底怎么执行的

在对上述大概了解过后,就可以深入查看其源码了。

先来看看这段代码:

LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);

我们先来分析在执行list.add(1);方法时,它的底层是怎么做的?

使用debug,step into add方法:
在这里插入图片描述

在add方法中,主要调用了一个linkLast方法:
在这里插入图片描述

  • 141:首先将Node类型的对象l指向我们的last对象,此时last为null,因为我们是第一次执行add操作,所以这里的对象l被赋值为null;
  • 142:又去创建了一个节点newNode,将l对象作为prev,e(我们所add的对象)作为节点项,next为null;
  • 143:将last指向newNode,也就是我们刚刚创建的节点;
  • 144:此时的l为null,所以这里会进入if判断语句内,将fist也指向newNode节点对象,这个时候,我们链表大致如下图所示:
    在这里插入图片描述
  • 148~149:增加链表大小和修改次数。

继续往下看list.add(2)方法:
前面还是不变,我们直接来到linkLast方法:
在这里插入图片描述
分析:

  • 141:创建Node类型的对象l指向我们的last对象,此时的last不再是null了,因为我们前面执行了一次add(1)操作,执行完这一步,链表如下图:
    在这里插入图片描述

  • 142:创建了一个节点newNode,将l对象作为prev(也就是将改Node对象的prev指向l节点对象),e(我们所add的对象)作为节点项,next为null,此时,链表如下图:
    在这里插入图片描述

  • 143:将last指向newNode;
    在这里插入图片描述

  • 144:指向到if判断时,此时l已经不为null了,所以去指向else语句,l.next = newNode,将l节点的next指向newNode;
    在这里插入图片描述

这就是完整的LinkedList的add操作流程,就是这么妙。

LinkedList的remove方法底层怎么做的?

在LinkedList中有很多remove方法:
在这里插入图片描述
这里我们主要来看看remove()这个方法。

再来看一段代码:

LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
list.remove();

remove方法默认是删除链表的第一个元素。

可以看到,在remove方法中,主要执行了removeFirst方法。
在这里插入图片描述
在这里插入图片描述
分析:

  • 268:创建一个Node对象f,将first指向的节点对象赋值给它;
    在这里插入图片描述

  • 271:如果它不为空,则执行unlinkFirst方法;

在这里插入图片描述
分析:

  • 173:取出f指向的节点中的item数据项;

  • 174:创建一个Node对象next,将它指向f.next节点;
    在这里插入图片描述

  • 175~176:f.item = null ; f.next = null
    在这里插入图片描述

  • 177:将first指向刚刚创建的next对象;
    在这里插入图片描述

  • 178:这里判断next此时不为null,所以会执行else语句,将next的prev置为null;
    在这里插入图片描述

整理一下图:
在这里插入图片描述
执行到这里,你会神奇的发现,需要删除的这个节点元素已经完全脱离我们链表了。

  • 182~184:将链表大小减去1,自增修改字数,返回被删除的元素;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值