Chain Table Simulation of #Java LinkedList Collection

Simple simulation of the implementation of two-way chain table in idle time, when you consolidate your knowledge and deepen your understanding, many people say that you can't bear eight-part articles, which is normal, because you can't understand its principle without experiencing the bottom implementation, so you can easily forget it when you have a dry back eight-part articles.

Introduction to Chain List

LinkedList, which is a two-way Chain table, is a common list in a collection where each node holds the data of the upper and lower nodes, allowing us to traverse them in the reverse and forward direction.

Chain List Simulation

Needless to say, we started simulating and looked at the bottom of the LinkedList and knew that when using LinkedList, data is not stored directly in the LinkedList, but encapsulated using its internal class Node (source code display):

// LinkedList's Internal Node Class
private static class Node<E> {
    E item; // Stored element Ontology
    Node<E> next; // Next node of the node where the element is located
    Node<E> prev; // The previous node of the node where the element is located
    // The constructor of a node
    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element; = next;
        this.prev = prev;

So all we have to do is implement the overall structure of the list first (here I implement the class name myself and add Sim to distinguish it)

// LinkedList Chain List Simulation Class
public class LinkedListSim {
    // First node of chain table
    NodeSim first;
    // End of chain list
    NodeSim last;
    // Record the length of the chain table
    int size;

    // Node node impersonation class (setter/getter implementation omitted)
    private static class NodeSim { 
        Object date; // Element Ontology
        NodeSim next; // Last Node
        NodeSim prev; // Next Node

        public String toString() {
            return "NodeSim{" +
                    "prev=" + prev +
                    ", next=" + next +
                    ", data=" + data +

A simple two-way chain table simulation class is completed. In fact, it is not complex to simulate the structure of a chain table, but if there is only one chain table structure, it is not enough, so it is worthless to not use it.



To make the chain table flexible, we need to make it have basic CRUD operations, first implement its add() method

 * Add Elements
 * @param data Elements to be added
public void add(Object data) {
    // Encapsulate data as Node node
    NodeSim node = new NodeSim();
    // If first is null, the first element is added
    if (first == null) {
        // Because it is the first element, the first and last nodes are all it, and it has no upper and lower nodes
        first = node;
        last = node;
    } else {
        // Otherwise, the element has been added
        node.setPrev(last); // The current tail node is the previous node of the new element
        node.setNext(null); // This node is the end node so there is no next node
        // The next node of the current endpoint changes to that node
        // Current End Changed to New End
        last = node;
    size ++;

After implementing the add() method, we test it with debug to see if the element can be successfully saved. We break the breakpoint here and use the debug interface to see if the first node is "a" and the end node is "c"

When the breakpoint goes down a step, that is, when all the data is added, we find that the data saved by the first and last nodes in the chain table is as expected. To be sure, we open the next node of the first node and the prev node of the end node to see if it is the intermediate element "b"

As shown in the diagram, as expected, each node that stores elements correctly saves its upper and lower nodes



We know that LinkedList and ArrayList look up in a completely different way, depending on how they are implemented at the bottom. ArrayList uses arrays at the bottom, so the feature is to support random subscript access, whereas LinkedList is implemented at the bottom as a chain table, which does not support subscript access. Can java provide us with subscript lookup for LinkedList, why?

The reason is simple: LinkedList's subscript lookup is not really through subscripts, but traverses the current node's next node one by one from the first node until the target result is obtained after traversing to index

(Because a list of chains, except first and last, does not directly know where the node is in the list, it can only start with first or last)

First and last node

Well, after talking about the native LinkedList, let's implement the lookup class api for our own chain list. We know that there are two key attributes in the LinkedList chain table, first and last, which store the first and last nodes of the whole chain table directly, so no matter how long the chain table is, when we only want to get the first and last nodes, it's as efficient and time consuming (so it's very fast to get directly).

 * Get the first node element
 * @return First Node Element
public Object getFirst() {
    return first.getData();

 * Get End Element
 * @return End element
public Object getLast() {
    return last.getData();

Chain List Length

Viewing the number (length) of elements in a collection is also a required function, but it is very simple for a chain table, simply returning the size in the attribute

 * Get Link List Length
 * @return Chain List Length
public int getSize() {
    return size;

Subscript Lookup

It is impossible for a collection to look only at its length or at its end and end nodes, so we need it to support subscript lookup (not real subscripts).

 * Gets the element through the subscript
 * @param index The element subscript
 * @return This element
public Object get(int index) {
    // If the lookup subscript is 0, the first node is found, and the first node is returned directly
    if (index == 0) {
        return getFirst();
    } else if (index == (size - 1)) {
        //If Find Subscript is Chain List Total Length-1 then Find End, Return to End
        return getLast();

    // Get Chain Header Element
    NodeSim node = first;
    for (int i = 0; i < index; i++) {
        node = node.getNext(); // Take the next node of this node
    // Target elements are obtained by traversing through index next s
    return node.getData();


After implementing several key api s, we'll do a unified test to see if we get the right results

(I won't debug it for convenience, just print it)

test data

LinkedListSim link = new LinkedListSim();


Get the chain length getSize() and get the first and last node getFirst()/getLast()

System.out.println("Chain list length:" + link.getSize());
System.out.println("First element:" + link.getFirst());
System.out.println("Tail element:" + link.getLast());

Result Display


Gets an index element specified in the chain table

System.out.println("Get the element with subscript 0:" + link.get(0)); // It's equivalent to getting the first node
System.out.println("Get the element with subscript 3:" + link.get(3));

We know that index=0 represents the first element of the set (the first node in the chain table), which has been optimized in the get() method implementation above, and when we look for it, if index equals the first and last nodes, we can simply go back to the first and last nodes.

Simulation Complete

In this LinkedList chain table simulation, I have carried out a simple addition and lookup operation. Have you been inspired? If in doubt you can leave your frustration in the comments, if you have any insights you can try to challenge yourself to implement and test changes and deletions to see if you can do it on your own

Tags: Java data structure linked list

Posted by madkris on Wed, 01 Jun 2022 16:31:28 +0530