LinkedList源码解析

LinkedList 源码解析

LinkedList 是有双向链表构成的

先来看一下LinkedList的构造器

transient 为不可序列化的标志

size为LinkedList的长度

transient int size = 0;

/**

first 是头节点的意思

* Pointer to first node.
*/
transient Node first;

last参数为尾节点的意思

/**
* Pointer to last node.
*/
transient Node last;

一个静态内部类节点

private static class Node {

​ item :存的值

​ E item;

​ next:存前节点的地址

​ Node next;

​ prev 存后节点的地址

​ Node prev;

​ Node(Node prev, E element, Node next) {

​ this.item = element;
​ this.next = next;
​ this.prev = prev;
​ }
}

LinkedList集合添加元素都是直接间接的调用linkFirst,linkLast这两种方法

这是linkFirst的方法,这要涉及到链表的知识,如果不知道,就可以去复习一下C语言的链表,很有帮助

    /**
     * Links e as first element.
     */
    private void linkFirst(E e) {
        //把头节点的地址值赋给f
        final Node<E> f = first;
        //创建一个新的节点,并赋予初始值,并赋予初始值,让next指向之前的first节点
        final Node<E> newNode = new Node<>(null, e, f);
        //重新重置first的值,让它等于新的节点
        first = newNode;
        //第一次添加的时候,还没有值,这个时候头节点等于尾节点
        if (f == null)
            last = newNode;
        else
        //让之前的值得pre节点指向第一个节点
        //
            f.prev = newNode;
        size++;
        modCount++;
       //集合长度加一,修改的次数也加一
       //这样first节点重置为新创建的节点
       //然后new的节点就一个tmp节点,每次插入数据后就是把地址重新复制给first节点
       //然后创建的f节点就是哪里接之前的first节点,然后让之前的first的节点的pre指正指向
       //最想的first节点,然后如此循环,就创建出了一个链表
    }

请添加图片描述

    //相同的原理,只是换个位置用last节点作用承接
	/**
     * 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++;
    }

接下来来介绍一下LinkedList其他的方法

  	//这个代码要从宏观的角度去看
	/**
     * Inserts element e before non-null Node succ.
     */
    void linkBefore(E e, Node<E> succ) {
        // assert succ != null;
        //创建一个succ指向的前面的节点
        final Node<E> pred = succ.prev;
        //创建一个新的节点,并且链接pre和succ节点
        final Node<E> newNode = new Node<>(pred, e, succ);
        //改变链接让succ的pre节点指向new节点
        succ.prev = newNode;
        //如果插入的节点的为头节点
        if (pred == null)
            first = newNode;
        else
        //不是头节点的话,让pred节点的next节点指向new节点
            pred.next = newNode;
        size++;
        modCount++;
    }

这是我画的理解图

请添加图片描述

//这是一个取消连接第一个节点的
private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
    	
        final E element = f.item;
        final Node<E> next = f.next;
    	//使item,next都为空
        f.item = null;
        f.next = null; // help GC
    	//让first节点等于next的节点
        first = next;
    	//如果next节点为空的换,让last也置空,然后此节点然后就是为空了
        if (next == null)
            last = null;
        else
            //让next的上个节点为空
            next.prev = null;
    	//linkedList的容量减一
        size--;
        modCount++;
    	//返回这个元素
        return element;
    }
   //让next的上个节点为空
            next.prev = null;
    	//linkedList的容量减一
        size--;
        modCount++;
    	//返回这个元素
        return element;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个不爱学习的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值