Java collection framework learning - List: How LinkedList builds a doubly linked list

Table of contents

structure

source code


Data structures are sometimes easy to understand, but difficult to implement. Let's learn how to build a doubly linked list in Java's collection framework

In Java's collection framework, LinkedList is a data storage class based on a doubly linked list structure, which has the characteristics of slow query and fast addition and deletion . Let's learn its underlying source code implementation

First the pattern opens

public class test01 {
    public static void main(String[] args) {
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("你好");
        linkedList.add("中国");
        linkedList.add("我爱你");
        System.out.println(linkedList);
    }
}

structure

Before looking at the source code, familiarize yourself with the internal structure of LinkedList

Among them, Node is its static internal class, which is an important part of realizing the doubly linked list structure, which can be called node

    private static class Node<E> {
        E item; //节点值:value
        Node<E> next; //下一个节点的地址
        Node<E> prev; //上一个节点的地址

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

size refers to the length of the linked list

source code

When the LinkedList instance object is initially created, the values ​​of the two Node properties are both null, and then call the add() method to add elements

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

As shown in the picture:

When adding the first element, it is both the head node and the tail node. You only need to create this object and point the pointer of the head and tail nodes to the address value where it is located.

When adding the second element, you need to go through the statement of the if branch. At this time, the local variable l is no longer null, so when we create a new element, we need to point the prev attribute pointer of the new element to the previous element, and point the tail node pointer to the new element, while the next attribute of the previous element The pointer points to the new element, so far the construction is complete.

Complete process:

  1. Put the tail node in the local variable l;
            final Node<E> l = last;
  2. Create a new node and point its own prev attribute to the previous node (here, because every time an element is added, the tail node pointer will point to the new element, so adding a new element again requires setting the prev attribute, and only needs to get the element of the current tail node. Can);
            final Node<E> newNode = new Node<>(l, e, null);
  3. Point the tail node pointer to the new node;
            last = newNode;
  4. Get the next attribute of the previous node and point to the new node
            if (l == null)
                first = newNode;
            else
                l.next = newNode;

 

 

Guess you like

Origin blog.csdn.net/Ccc67ol/article/details/130477352