LinkedList in Java – Complete Guide with Examples

1. Introduction

  • The LinkedList class in Java is part of the java.util package.
  • It implements both the List and Deque interfaces, which means it can be used as a List, Queue, or Deque (Double Ended Queue).
  • Unlike ArrayList, which is backed by a dynamic array, LinkedList is backed by a doubly-linked list.

👉 Declaration:

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

2. Internal Working of LinkedList

LinkedList in Java is implemented as a doubly-linked list, meaning each node contains references to both the previous and next nodes. This structure allows efficient insertion and deletion from both ends of the list.

  • Each element (called a Node) contains:
    • Data
    • Reference to the previous node
    • Reference to the next node
  • The LinkedList maintains head (first element) and tail (last element).
  • This structure allows efficient insertions and deletions but slower random access compared to ArrayList.

Diagram (for visualization):

Head <-> Node1 <-> Node2 <-> Node3 <-> Tail

3. Creating a LinkedList

import java.util.LinkedList;

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

        // Adding elements
        list.add("Apple");
        list.add("Banana");
        list.add("Mango");

        System.out.println(list); // [Apple, Banana, Mango]
    }
}

4. Commonly Used Constructors

  • LinkedList() → Creates an empty LinkedList
  • LinkedList(Collection<? extends E> c) → Creates a LinkedList containing elements of the given collection

5. Methods in LinkedList with Examples

(a) Adding Elements

list.add("Orange");         // add at end
list.addFirst("Grapes");    // add at beginning
list.addLast("Pineapple");  // add at end
list.add(2, "Kiwi");        // add at specific index

(b) Accessing Elements

System.out.println(list.get(0));       // by index
System.out.println(list.getFirst());   // first element
System.out.println(list.getLast());    // last element

(c) Updating Elements

list.set(1, "Strawberry");  // update at index

(d) Removing Elements

list.remove();            // removes first element
list.remove(2);           // removes element at index
list.remove("Mango");     // removes first occurrence
list.removeFirst();       // removes first element
list.removeLast();        // removes last element

(e) Searching Elements

System.out.println(list.contains("Apple")); // true/false
System.out.println(list.indexOf("Banana")); // returns index
System.out.println(list.lastIndexOf("Banana")); // last occurrence

(f) Iterating LinkedList

// Using for-each loop
for (String fruit: list) {
  System.out.println(fruit);
}

// Using iterator
Iterator < String > it = list.iterator();
while (it.hasNext()) {
  System.out.println(it.next());
}

// Using descending iterator
Iterator < String > descIt = list.descendingIterator();
while (descIt.hasNext()) {
  System.out.println(descIt.next());
}

(g) Queue & Deque Methods

Since LinkedList implements Deque:

list.offer("Watermelon");   // add at end
list.offerFirst("Papaya");  // add at beginning
list.offerLast("Guava");    // add at end

System.out.println(list.peek());       // view head
System.out.println(list.peekFirst());  // view first
System.out.println(list.peekLast());   // view last

System.out.println(list.poll());       // remove and return head
System.out.println(list.pollFirst());  // remove and return first
System.out.println(list.pollLast());   // remove and return last

6. Time Complexity of LinkedList Operations

OperationTime Complexity
Add at beginning (addFirst)O(1)
Add at end (addLast / add)O(1)
Add at specific indexO(n)
Remove first/lastO(1)
Remove at index/valueO(n)
Get element by indexO(n)
Search (contains, indexOf)O(n)
IterationO(n)

👉 When to use LinkedList?

  • When frequent insertions and deletions are needed.
  • Not suitable when frequent random access is required (use ArrayList instead).

7. LinkedList vs ArrayList

FeatureArrayListLinkedList
Data StructureDynamic ArrayDoubly Linked List
Access Time (get)O(1)O(n)
Insert/Delete at endO(1)O(1)
Insert/Delete at startO(n)O(1)
Memory UsageLessMore (extra node pointers)

8. Real-World Use Cases

  • Implementing Undo/Redo functionality (backed by LinkedList).
  • Navigation (next/previous pages) in browsers.
  • Queue/Deque implementations.

9. Conclusion

  • LinkedList is best for insertion/deletion-heavy operations.
  • For random access, prefer ArrayList.
  • Knowing both helps in choosing the right data structure for performance optimization.

Backend developer working with Java, Spring Boot, Microservices, NoSQL, and AWS. I love sharing knowledge, practical tips, and clean code practices to help others build scalable applications.

Leave a Reply

Your email address will not be published. Required fields are marked *