Table of contents
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:
- Put the tail node in the local variable l;
final Node<E> l = last;
- 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);
- Point the tail node pointer to the new node;
last = newNode;
- Get the next attribute of the previous node and point to the new node
if (l == null) first = newNode; else l.next = newNode;