Clean • Professional
The LinkedList class in Java is a versatile, node-based linear data structure that is part of the Java Collections Framework.
It implements:
Unlike ArrayList, it is not array-backed, but node-backed, making it ideal for insertion and deletion-heavy use cases.
A LinkedList is a doubly-linked data structure where each element is stored in a separate node, containing:
Because the nodes are linked dynamically, size can grow or shrink anytime.
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
}
NULL ← [ Prev | Data: A | Next ] ↔ [ Prev | Data: B | Next ] ↔ [ Prev | Data: C | Next ] → NULL
This allows O(1) insertions at both ends.
Iterable
└── Collection
└── List
└── LinkedList
└── implements Deque
Because LinkedList implements Deque, it also supports:
| Feature | Explanation |
|---|---|
| Dynamic Size | Grows and shrinks automatically |
| Fast Insert/Delete | No shifting like ArrayList |
| Slow Access | Because nodes must be traversed |
| Implements List, Queue, Deque | Very flexible |
| Allows Null | Yes |
| Allows Duplicates | Yes |
| Random Access | Not supported (O(n) performance) |
Use LinkedList when:
Avoid LinkedList when:
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++]
LinkedList<E> list = new LinkedList<>(); // empty list
LinkedList<E> list2 = new LinkedList<>(list1); // copy another collection

Below are all important methods, grouped with examples.
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");
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();
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();
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++");
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();
| Operation | Complexity | Explanation |
|---|---|---|
| addFirst / addLast | O(1) | Insertion at head or tail is constant-time because only pointers change. |
| removeFirst / removeLast | O(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). |
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);
}
}