How to Create Generic LinkedList in Java

Suraj P Feb 02, 2024
  1. a Brief Introduction to LinkedList in Java
  2. a Generic Implementation of Singly LinkedList in Java
How to Create Generic LinkedList in Java

This article will teach us how to create a generic singly LinkedList in Java.

a Brief Introduction to LinkedList in Java

LinkedLists are linear data structures that store data in nodes at random addresses and means at non-contiguous locations.

Every node has two parts: data and reference(address). The Data/value field stores the value, and the reference field stores the address of the next node of the linked list.

Some of the common operations of this data structure that will implement as member functions are as follows.

  1. addNode() - This method is used to add a new element at the end of the LinkedList.
  2. removeNode(value) - This method removes the node with the specified value.
  3. addNode(position,value) - This method is used to add the value at a specific position.
  4. clear() - This method clears the entire LinkedList.
  5. isEmpty() - This method is used to check whether the LinkedList is empty or not.
  6. length() - This method gives us the length of the LinkedList.

a Generic Implementation of Singly LinkedList in Java

A normal LinkedList can only store one type of value: integer, string, boolean, float, etc. So we have to specify the type at the time of creation, but what if we want to create the LinkedList, which can store data of any data type; for that, we will use the concept of generics in Java.

Creating generic node class:

In the below code, T denotes the type of data stored on LinkedList.

class Node<T> {
  T value;
  Node<T> nextPtr;

  Node(T value) {
    this.value = value;
    this.nextPtr = null;
  }
}

Now let’s create the generic LinkedList class creating methods.

  1. add() function:

    void add(T value) {
      Node<T> temp = new Node<>(value); // creating a new node
    
      if (this.head == null) // checking if the list is empty
        head = temp;
    
      else // if the list is not empty, we go till the end and add the node
      {
        Node<T> tr = head;
        while (tr.nextPtr != null) {
          tr = tr.nextPtr;
        }
    
        tr.nextPtr = temp;
      }
    
      length = length + 1; // increasing the length of list
    }
    
  2. remove() function:

    void remove(T key) {
      Node<T> prev = new Node<>(null);
      prev.nextPtr = head;
      Node<T> next = head.nextPtr;
      Node<T> tr = head;
    
      boolean isNodepresent = false; // to check if node is present
    
      if (head.value == key) {
        head = head.nextPtr;
        isNodepresent = true;
      }
    
      while (tr.nextPtr != null) {
        if (String.valueOf(tr.value).equals(
                String.valueOf(key))) { // if the node is present, we break the loop
          prev.nextPtr = next; // we assign previous node's nextPtr to next node
          isNodepresent = true;
          break;
        }
    
        prev = tr; // updating the previous and next pointers
        tr = tr.nextPtr;
        next = tr.nextPtr;
      }
    
      if (isNodepresent == false && String.valueOf(tr.value).equals(String.valueOf(key))) {
        prev.nextPtr = null;
        isNodepresent = true;
      }
    
      if (isNodepresent) {
        length--; // if the node is present, we reduce the length
      }
    
      else {
        System.out.println("The value is not present inside the LinkedList");
      }
    }
    
  3. add(position,value) function:

    void add(int position, T value) {
      if (position > length + 1) // if the position entered is more than the list length
      {
        System.out.println("Position out of bound");
        return;
      }
    
      if (position == 1) { // if the position is one we'll just
        Node<T> temp = head;
        head = new Node<T>(value);
        head.nextPtr = temp;
        return;
      }
    
      Node<T> tr = head;
      Node<T> prev = new Node<T>(null); // creating a new node prev
    
      while (position - 1 > 0) // we find the position in the list
      {
        prev = tr;
        tr = tr.nextPtr;
        position--;
      }
    
      prev.nextPtr = new Node<T>(value); // update the next pointer of previous node
      prev.nextPtr.nextPtr = tr;
    }
    
  4. getLength() function:

    int getLength() {
      return this.length; // returns the length of the list
    }
    
  5. isEmpty() function:

    boolean isEmpty() {
      if (head == null) // if the list is empty we return true
        return true;
    
      else
        return false;
    }
    
  6. clear() function:

    void clear() {
      head = null; // make head as null and length as zero
      length = 0;
    }
    
  7. toString() function:

    In the below code, we have added and overridden the toString method to print the contents of the LinkedList.

    @Override
    public String toString() {
      Node<T> temp = head;
      String str = "{ ";
      if (temp == null) // if the list is empty
      {
        System.out.println("list is empty");
      }
    
      while (temp.nextPtr != null) // we keep appending data to string till the list is empty
      {
        str += String.valueOf(temp.value) + "->";
        temp = temp.nextPtr;
      }
    
      str += String.valueOf(temp.value);
      return str + "}"; // we finally return the string
    }
    

Full working code with main class:

class Node<T> {
  T value;
  Node<T> nextPtr;

  Node(T value) {
    this.value = value;
    this.nextPtr = null;
  }
}

class LinkedList<T> {
  Node<T> head;
  private int length = 0;

  LinkedList() {
    this.head = null;
  }

  void add(T value) {
    Node<T> temp = new Node<>(value);

    if (this.head == null)
      head = temp;
    else {
      Node<T> tr = head;
      while (tr.nextPtr != null) {
        tr = tr.nextPtr;
      }

      tr.nextPtr = temp;
    }
    length = length + 1;
  }

  void remove(T key) {
    Node<T> prev = new Node<>(null);
    prev.nextPtr = head;
    Node<T> next = head.nextPtr;
    Node<T> tr = head;

    boolean isNodepresent = false;

    if (head.value == key) {
      head = head.nextPtr;
      isNodepresent = true;
    }

    while (tr.nextPtr != null) {
      if (String.valueOf(tr.value).equals(String.valueOf(key))) {
        prev.nextPtr = next;
        isNodepresent = true;
        break;
      }

      prev = tr;
      tr = tr.nextPtr;
      next = tr.nextPtr;
    }

    if (isNodepresent == false && String.valueOf(tr.value).equals(String.valueOf(key))) {
      prev.nextPtr = null;
      isNodepresent = true;
    }

    if (isNodepresent) {
      length--;
    }

    else {
      System.out.println("The value is not present inside the LinkedList");
    }
  }

  void add(int position, T value) {
    if (position > length + 1) {
      System.out.println("Position out of bound");
      return;
    }

    if (position == 1) {
      Node<T> temp = head;
      head = new Node<T>(value);
      head.nextPtr = temp;
      return;
    }

    Node<T> tr = head;
    Node<T> prev = new Node<T>(null);

    while (position - 1 > 0) {
      prev = tr;
      tr = tr.nextPtr;
      position--;
    }

    prev.nextPtr = new Node<T>(value);
    prev.nextPtr.nextPtr = tr;
  }

  int getLength() {
    return this.length;
  }

  boolean isEmpty() {
    if (head == null)
      return true;

    else
      return false;
  }

  void clear() {
    head = null;
    length = 0;
  }

  @Override
  public String toString() {
    Node<T> temp = head;
    String str = "{ ";
    if (temp == null) {
      System.out.println("list is empty");
    }

    while (temp.nextPtr != null) {
      str += String.valueOf(temp.value) + "->";
      temp = temp.nextPtr;
    }

    str += String.valueOf(temp.value);
    return str + "}";
  }
}

public class Example {
  public static void main(String[] args) {
    LinkedList<Integer> ll = new LinkedList<>();
    ll.add(1);
    ll.add(2);
    ll.add(3);

    System.out.println(ll);

    ll.remove(3);
    System.out.println(ll);

    ll.add(2, 800);
    System.out.println(ll);
  }
}

Output:

{ 1->2->3}
{ 1->2}
{ 1->800->2}
Author: Suraj P
Suraj P avatar Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn GitHub

Related Article - Java LinkedList