Java集合LinkedList集合源码解析

LinkedList定义了三个成员变量:

int size

Node<E> first

Node<E> last

Node是一个已经定义的内部类:
   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的构造方法:

LinkedList提供了两类构造方法:

 public LinkedList() {
    }


    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

第一种为默认的无参构造方法。

第二种构造方法传入的参数为实现了Collection接口的任意集合类型。

LinkedList 的方法

关键的几个内部方法(头部添加删除,尾部添加删除,获取指定节点,指定节点的添加删除)分析

在头部添加:linkFirst(E e):

 private void linkFirst(E e) {
        final Node<E> f = first;  //保存当前链表的头节点
        final Node<E> newNode = new Node<>(null, e, f);//新建节点,节点的next指向头节点
        first = newNode;  //链表的头节点更新为新建的节点
        if (f == null)    //对链表进行判断,如果链表为空,则新插入的节点作为头节点
            last = newNode;//如果之前的链表为空,则尾节点更新为新建的节点
        else
            f.prev = newNode;//则之前的头节点的pre指向新建的节点
        size++;
        modCount++;
    }
删除头节点:unlinkFirst(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;      //将节点的值和next置为null
        f.next = null; // help GC
        first = next;       //头节点更新为下一个节点
        if (next == null)   //如果当前的头节点是链表中的唯一的节点
            last = null;    //尾节点置为null
        else
            next.prev = null;//下一个节点的pre设为
        size--;
        modCount++;
        return element;
    }


在尾部添加:LinkLast(E e)

  void linkLast(E e) {
        final Node<E> l = last;  //保存当前的尾节点信息
        final Node<E> newNode = new Node<>(l, e, null);//新建一个节点,节点的pre为之前的尾节点,next为null
        last = newNode;  //尾节点更新为新建的节点
        if (l == null)  //如果链表为空
            first = newNode;//头节点也更新为新建的节点
        else
            l.next = newNode;//修改之前的尾节点的next值为新建的节点
        size++;
        modCount++;
    }

删除尾部节点:unlinklast(E e)

 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;//将为节点的值和pre更改为null
        l.prev = null; // help GC
        last = prev;//更新尾节点为前一个节点
        if (prev == null)//如果当前节点为链表中的唯一节点
            first = null;//头节点为null
        else
            prev.next = null;
        size--;
        modCount++;
        return element;
    }

指定节点前的添加

void linkBefore(E e, Node<E> 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);//新建节点,节点的pre为指定节点的前一个节点,next为指定节点
        succ.prev = newNode;     //修改指定节点的pre为新建节点
        if (pred == null)        //如果指定节点为头节点
            first = newNode;      //first指向新建的节点
        else
            pred.next = newNode; //指定节点的前一个节点的next为新建节点
        size++;
        modCount++;
    }

删除指定节点

 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;      //first指向删除节点的后一个节点
        } else {
            prev.next = next;   //删除节点的前一个节点的next指向删除节点的后一个节点
            x.prev = null;   
        }

        if (next == null) {   //如果删除的是尾节点
            last = prev;   //last指向删除节点的前一个节点
        } else {
            next.prev = prev;//删除节点的后一个节点pre指向删除节点的前一个节点
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
    }

获取指定节点

 Node<E> node(int index) {
        // assert isElementIndex(index);
         //对index进行判断,如果index位于链表的前一半,则正序查找
        if (index < (size >> 1)) {     
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {            //如果index位于链表的后一半,则倒序查找
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

LinkedList 特点

  • 双向链表实现
  • 元素时有序的,输出顺序与输入顺序一致
  • 允许元素为 null
  • 所有指定位置的操作都是从头开始遍历进行的
  • 和 ArrayList 一样,不是同步容器





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值