ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JDK源码之LinkedList

2021-09-27 19:59:50  阅读:161  来源: 互联网

标签:Node null LinkedList JDK pred next 源码 newNode prev


JDK源码之LinkedList

1. 全局变量

// 列表容量
transient int size = 0;
// 指向第一个节点的指针
transient Node<E> first;
// 指向最后一个节点的指针
transient Node<E> last;

2. 构造器

// 构建一个空list
public LinkedList() {
}
// 构建一个包含c的list
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

tip:使用this关键字调用重载构造方法,避免相同的初始化代码,只能在构造方法中使用,必须位于构造方法的第一句。

3. 增删用到的双向链表的方法

双向链表是linkedList的基础。

// 将元素e作为linkedList最后一个元素;
void linkLast(E e) {final Node<E> l = last; //取原本的最后一个节点
    final Node<E> newNode = new Node<>(l, e, null); // new一节点
    last = newNode; // 将新节点赋值给last
    if (l == null) // 前一个节点链接上新节点
        first = newNode;
    else
        l.next = newNode;
    size++; //更新size和修改次数
    modCount++;}
// 将元素e作为linkedList第一个元素
private void linkFirst(E e) {final Node<E> f = first; //取原本的第一个节点
    final Node<E> newNode = new Node<>(null, e, f); // new一个节点
    first = newNode; //将新节点赋值给last
    if (f == null)//后一个节点链接上新节点
        last = newNode;
    else
        f.prev = newNode;
    size++; //更新size和修改次数
    modCount++;}
// 去掉链表中首个元素f
private E unlinkFirst(Node<E> f) {
    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;}
// succ节点前插入一个元素e
void linkBefore(E e, Node<E> succ) {
    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++;}
// 去掉非null的最后一个元素
private E unlinkLast(Node<E> l) {
    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;}
// 去除某个非null元素
E unlink(Node<E> x) {
    final E element = x.item;// 1. 保存x节点的元素,前后元素的指针
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;
    if (prev == null) {    // 2. x前一个元素链接x后一个元素
        first = next;} else {
        prev.next = next;
        x.prev = null;}
    if (next == null) { //3. x后一个元素链接x前一个元素
        last = prev;} else {
        next.prev = prev;
        x.next = null;}
    x.item = null;// 更新元素,容量和变更次数
    size--;
    modCount++;
    return element;}

对于中间位置元素的增删,下面两个图可以很好的表示操作步骤:
插入操作示意图:(在c之前加入c1节点)
在这里插入图片描述
删除操作示意图:(删除c节点)
在这里插入图片描述

4. 方法

//在index位置插入c
public boolean addAll(int index, Collection<? extends E> c) {
    checkPositionIndex(index);
    Object[] a = c.toArray();
    int numNew = a.length;
    if (numNew == 0)return false;
    Node<E> pred, succ;
    if (index == size) {
    	succ = null;// 取出插入位置前后元素
        pred = last; 
    } else {
        succ = node(index);
        pred = succ.prev;
    }
    for (Object o : a) { //循环添加
        @SuppressWarnings("unchecked") E e = (E) o;
        Node<E> newNode = new Node<>(pred, e, null);
        if (pred == null) //新链表
            first = newNode;
        else
            pred.next = newNode;
        pred = newNode; 
    }
    if (succ == null) {	//添加完后链接起来
        last = pred;
    } else {
        pred.next = succ;
        succ.prev = pred;
    }
    size += numNew;
    modCount++;
    return true;
}

5. 特性

LinkedList继承了Deque接口,具有队列的特性,同时作为双端队列,LinkedList还具有栈的特性。

队列方法:队列方法
栈:

public void push(E e) {
    addFirst(e);
}

public E pop() {
    return removeFirst();
}

6. ArrayList和LinkedList不同

  1. LinkedList不支持随机访问,因此访问非首尾元素效率较低,时间复杂度为O(n),访问首尾时间复杂度为O(1)。
  2. 相比于ArrayList, LinkedList的优势在于插入、删除操作,只需要改变前后两个元素的指针,不需要移动后面的元素。
  3. LinkedList由双向链表实现,具有队列和栈的特性。ArrayList由数组实现。

标签:Node,null,LinkedList,JDK,pred,next,源码,newNode,prev
来源: https://blog.csdn.net/weixin_43300285/article/details/120515591

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有