LinkedList源码分析

LinkedList集合源码分析

  • 底层数据结构是双链表
  • 特点是:查询慢,增删快,但是如果操作的是首尾元素,速度也是极快

底层数据结构是双链表,查询慢,首尾操作的速度是极快的,所以多了很多首尾操作的API。

特有方法 说明

public void addFirst(E e) 在该列表的开头插入指定的元素

public void addLast(E e) 将指定的元素追加到此列表的末尾

public E getFirst() 返回此列表中的第一个元素

public E getLast() 返回此列表中的最后一个元素

public E removeFirst() 从此列表中删除并返回第一个元素

public E removeLast() 从此列表中删除并返回最后一个元素

首先,先把源码重要部分扒取下来

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;
    }
}

这一部分是属于

java.util.LinkedList包下,同时也是LinkedList的内部类,Node代表的就是结点的对象

分析这三个成员变量

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;
}

每创建一个节点,就要把那三个数据传递过来才可以

接下来又来看这段源码

public class LinkedList<E>  extends AbstractSequentialList<E>  implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient int size = 0;

    /**
     * Pointer to first node.
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     */
    transient Node<E> last;

    /*
    void dataStructureInvariants() {
        assert (size == 0)
            ? (first == null && last == null)
            : (first.prev == null && last.next == null);
    }
    */

    /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }
transient int size = 0;

/**
 * Pointer to first node.
 */
transient Node<E> first;

/**
 * Pointer to last node.
 */
transient Node<E> last;

在LinkedList源码中发现这里有三个成员变量

第一个size=0,这里不仅表达了结点个数,也表示了集合长度

第二和第三分别表示了头结点和尾结点

然后就是空参构造,也就是说,当我们使用空参构造的时候,前面三个成员变量就会随之加载进来

接下来我们来一段代码看看执行流程:

LinkedList<String> list=new LinkedList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");

我们直接调用add方法添加"aaa",进入源码

public boolean add(E e) {
    linkLast(e);
    return true;
}

又进入linkLast()方法

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++;
}

这里我就使用图片演示了

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;
    }
}

posted @ 2022-11-09 22:30  喜欢七岁就很浪  阅读(33)  评论(0编辑  收藏  举报