C

Core Java tutorial for beginners

Clean • Professional

LinkedList in Java – Features, Internals, Methods & Examples

5 minute

LinkedList in Java

The LinkedList class in Java is a versatile, node-based linear data structure that is part of the Java Collections Framework.

It implements:

  • List (ordered collection)
  • Deque (double-ended queue)
  • Queue (FIFO operations)
  • Cloneable & Serializable

Unlike ArrayList, it is not array-backed, but node-backed, making it ideal for insertion and deletion-heavy use cases.


What is LinkedList in Java?

A LinkedList is a doubly-linked data structure where each element is stored in a separate node, containing:

  • Data
  • Pointer to Previous Node
  • Pointer to Next Node

Because the nodes are linked dynamically, size can grow or shrink anytime.

Internal Structure of LinkedList

LinkedList Node Structure

Each element in LinkedList is stored as a Node object:

class Node<E> {
    E item;       // Data
    Node<E> next; // Pointer to next
    Node<E> prev; // Pointer to previous
}

Memory Diagram

NULL ← [ Prev | Data: A | Next ] ↔ [ Prev | Data: B | Next ] ↔ [ Prev | Data: C | Next ] → NULL
  • LinkedList maintains pointers to:
    • first node → head
    • last node → tail

This allows O(1) insertions at both ends.

LinkedList in Java Collection Hierarchy

Iterable
   └── Collection
          └── List
                └── LinkedList
                           └── implements Deque

Because LinkedList implements Deque, it also supports:

  • Queue (FIFO)
  • Stack (LIFO)

Key Features of LinkedList

FeatureExplanation
Dynamic SizeGrows and shrinks automatically
Fast Insert/DeleteNo shifting like ArrayList
Slow AccessBecause nodes must be traversed
Implements List, Queue, DequeVery flexible
Allows NullYes
Allows DuplicatesYes
Random AccessNot supported (O(n) performance)

When to Use LinkedList?

Use LinkedList when:

  • Frequent insertion/deletion at head/tail
  • Implementing Queue (FIFO)
  • Implementing Stack (LIFO)
  • Real-time data processing
  • When you need constant-time insertion
  • When key operations are add/remove, not get()

Avoid LinkedList when:

  • You need fast random access → use ArrayList
  • Memory is limited
  • You expect millions of elements (pointer-heavy)
  • You do frequent searching → O(n)

How to Create a LinkedList in Java

Example 1: Basic LinkedList

import java.util.LinkedList;

public class Main {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();

        list.add("Java");
        list.add("Python");
        list.add("C++");

        System.out.println(list);
    }
}

Output:

[Java, Python, C++]

Important LinkedList Constructors

LinkedList<E> list = new LinkedList<>();          // empty list
LinkedList<E> list2 = new LinkedList<>(list1);    // copy another collection

Commonly Used LinkedList Methods

learn code with durgesh images

Below are all important methods, grouped with examples.

1. Add Methods

add(E e)

Adds an element to the end of the LinkedList. This is efficient because no shifting is required—just pointer updates.

list.add("PHP");

add(int index, E element)

Inserts an element at a specific index. Requires traversal to reach the position, so it's slower than adding at ends.

list.add(1, "HTML");

addFirst(E e)

Adds an element at the beginning (head) of the list. Operation is very fast (O(1)).

list.addFirst("Start");

addLast(E e)

Adds an element at the end (tail) of the list. Also an O(1) operation.

list.addLast("End");

offer(E e)

Adds an element to the tail in a queue-friendly way; returns boolean instead of throwing exceptions.

list.offer("Data");

offerFirst(E e) Inserts an element at the head safely, returning true/false instead of exceptions.

list.offerFirst("First");

offerLast(E e)

Adds an element at the tail safely with a boolean result.

list.offerLast("Last");

2. Get Methods

get(int index)

Returns the element at the specified index; requires traversal because LinkedList has no random access.

list.get(2);

getFirst()

Retrieves the first (head) element of the list; throws exception if list is empty.

list.getFirst();

getLast()

Retrieves the last (tail) element; throws exception if the list is empty.

list.getLast();

peek(), peekFirst(), peekLast()

Returns the head or tail element without removing it, and returns null if empty (safe operations).

list.peek();
list.peekFirst();
list.peekLast();

3. Remove Methods

remove()

Removes and returns the first element; throws exception if list is empty.

list.remove();

remove(int index)

Removes the element at the specified position; traversal required to reach index.

list.remove(2);

removeFirst(), removeLast()

Removes and returns the first or last element; both throw exceptions if list is empty.

list.removeFirst();
list.removeLast();

poll(), pollFirst(), pollLast()

Removes and returns the element, but returns null instead of throwing an exception if the list is empty.

list.poll();

4. Search Methods

contains(Object o)

Checks whether the element exists in the list; performs a linear search.

list.contains("Java");

indexOf(Object o)

Returns the index of the first occurrence of the element, or -1 if not found.

list.indexOf("Python");

lastIndexOf(Object o)

Returns the index of the last occurrence of the element, or -1 if not found.

list.lastIndexOf("C++");

5. Misc Methods

size()

Returns the number of elements currently stored in the LinkedList.

list.size();

clear()

Removes all elements from the list, making it empty.

list.clear();

isEmpty()

Checks whether the list contains no elements; returns true if empty.

list.isEmpty();

Time Complexity of LinkedList

OperationComplexityExplanation
addFirst / addLastO(1)Insertion at head or tail is constant-time because only pointers change.
removeFirst / removeLastO(1)Deleting from head or tail updates pointers; no traversal needed.
add(index)O(n)List must traverse node-by-node to reach the given index.
remove(index)O(n)Needs traversal to find the index before removal.
get(index)O(n)No random access; traversal from head or tail is required.
contains()O(n)Searches every node until element is found (linear search).

Advantages of LinkedList

  • Best for insertion/deletion
  • Efficient queue and stack operations
  • No size limit
  • Useful for real-time apps
  • Implements Deque (so can replace Stack/Queue)

Disadvantages of LinkedList

  • Slow random access
  • High memory overhead
  • Poor cache locality
  • Traversal required

Real-World Use Cases of LinkedList

  • Playlist navigation (Next/Previous)
  • Undo/Redo (MS Word, editors)
  • Browser history
  • Task scheduling
  • Real-time messaging queue
  • Job processing (queues)
  • Print queue management

Complete Example with All Major Operations

import java.util.LinkedList;

public class Demo {
    public static void main(String[] args) {

        LinkedList<String> list = new LinkedList<>();

        list.add("A");
        list.add("B");
        list.add("C");

        list.addFirst("Start");
        list.addLast("End");

        System.out.println(list.get(2));
        System.out.println(list.getFirst());
        System.out.println(list.getLast());

        list.remove("B");
        list.removeLast();

        System.out.println(list.contains("C"));

        System.out.println(list);
    }
}

 

Article 0 of 0