🚩 Java collection: on LinkedList
📚 1. Use of LinkedList set
✒️ 1.1 simple use of LinkedList set
import java.util.LinkedList; public class TestDemo { public static void main(String[] args) { LinkedList<Integer> list = new LinkedList<>(); list.add(11); list.add(22); list.add(33); list.add(11); list.add(null); for (Integer value : list) { System.out.print(value + " "); } } }
Operation results:
🖊️ 1.2 LinkedList set features
1. The data is in order of insertion
2. Data can be inserted repeatedly
3. null values can be stored
4. The bottom layer adopts the data structure of two-way linked list
📕 2. Study the implementation of LinkedList through JDK source code
📫 2.1 inheritance
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
Class structure diagram:
① LinkedList inherits the AbstractSequentialList abstract class. AbstractSequentialList inherits from AbstractList and implements common methods to facilitate the direct reuse of subclasses.
② LinkedList also implements List, Cloneable and Java io. Serializable interface, which can realize cloning and serialization.
③ deque interface is implemented. This interface is a two terminal Queue interface, which inherits from the Queue interface. Therefore, LinkedList is also the implementation class of the Queue interface, and queues and stacks can be realized with the help of this Queue.
📪 2.2 properties and default values
//Number of valid data transient int size = 0; //Head node position transient Node<E> first; //Tail node position transient Node<E> last; //Node class 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; } }
From the Node class, we can see that the underlying layer of LinkedList is a data structure of two-way linked list.
📬 2.3 constructor
non-parameter constructor
public LinkedList() { }
Parameterized constructors parameterized constructors call nonparametric constructors and bulk add functions
public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
📭 2.4 common methods source code analysis
📑 2.4.1 add: add element
public boolean add(E e) { linkLast(e); return true; } void linkLast(E e) { final Node<E> l = last; //The new node takes the tail node of the linked list as the precursor, and inserts the new node into the tail of the linked list final Node<E> newNode = new Node<>(l, e, null); //Update the tail node and take the new node as the tail node last = newNode; if (l == null) //If the first node is currently inserted, point the head node to the new node. At this time, first = last = newNode first = newNode; else //The current inserted node is not the first node. The next field of the tail node of the original linked list points to the new node l.next = newNode; size++;//Number of effective elements + 1 modCount++; }
📄 2.4.2 remove: delete element
public boolean remove(Object o) { //Determine whether the deleted element is null if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); return true; } } } return false; } //Delete element logic 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; //Determine whether the deleted element is the first element if (prev == null) { //The deleted element is the first element, and the header node points to the second element first = next; } else { //The deleted element is not the first element //The successor of the previous node of the deleted element points to the next node of the deleted element //The precursor of the deleted element is set to null prev.next = next; x.prev = null; } //Determine whether the deleted element is the last element if (next == null) { //The deleted element is the last element, and the tail node points to its previous node last = prev; } else { //The deleted element is not the last element //The precursor of the last node of the deleted element points to the previous node of the deleted element //The successor of the deleted element is set to null next.prev = prev; x.next = null; } //Set the item of the deleted node to null x.item = null; size--;//Number of valid elements - 1 modCount++; return element; }
The precursor, successor and item of the Node are set to null to facilitate Node recycling
📃 2.4.3 get: get elements
public E get(int index) { //Check the validity of the subscript checkElementIndex(index); return node(index).item; } private void checkElementIndex(int index) { //If the subscript is illegal, a subscript out of bounds exception is thrown if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } //Check whether the subscript is between 0 and the limited range of size - 1 private boolean isElementIndex(int index) { return index >= 0 && index < size; } Node<E> node(int index) { // assert isElementIndex(index); //Use the binary search method to find elements //If the subscript is in the first half of size/2, look from front to back //If the subscript is in the second half of size/2, look from back to front if (index < (size >> 1)) { Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
🃏 3. Comparison between ArrayList and LinkedList
Bottom structure | Efficiency of addition and deletion | Efficiency of modification | |
---|---|---|---|
ArrayList | Variable array | Lower array expansion | higher |
LinkedList | Bidirectional linked list | Higher, added through linked list | Lower |
How to select ArrayList and LinkedList:
1. Select ArrayList if we have many operations to change the query
2. If we have many additions and deletions, select LinkedList
3. Generally speaking, in the program, 80% ~ 90% are queries, so ArrayList will be selected in most cases
4. In a project, it can be selected flexibly according to the business. One module uses ArrayList and the other module uses LinkedList