LinkedList
The doubly linked list behind LinkedList — nodes, head/tail, traversal cost, Deque operations and when it actually wins.
#Introduction
LinkedList is one of the most misunderstood classes in the Java Collections Framework. Many developers believe:
"LinkedList is always faster than ArrayList."
This is not true. A 5+ years Java developer is expected to know when LinkedList is better, when ArrayList is better, and how LinkedList works internally.
#What is LinkedList?
LinkedList is a doubly linked list implementation of the List interface.
Package:
java.util.LinkedListDeclaration:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>,
Deque<E>,
Cloneable,
SerializableNotice: unlike ArrayList, LinkedList implements List, Queue and Deque. That makes it much more versatile.
#Position in Collection Hierarchy
- Iterable
- Collection
- List
- LinkedList
- Queue
- Deque
- LinkedList
#Characteristics
- Maintains insertion order
- Allows duplicates
- Allows multiple null values
- Dynamic size
- Fast insertion/deletion after locating the position
- Slow random access
- Higher memory consumption
- Not thread-safe
#Internal Structure
Unlike ArrayList, LinkedList does NOT use an array. It uses Nodes. Each node stores:
- Data
- Previous node reference
- Next node reference
Node Class (Simplified)
Internally Java has something similar to:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.prev = prev;
this.next = next;
}
}Every element becomes a Node.
#Memory Representation
list.add("A");
list.add("B");
list.add("C");#Why a Doubly Linked List?
Suppose Java used a singly linked list. Backward traversal would not be possible, and removing a node would require finding its previous node. A doubly linked list allows:
- Forward traversal
- Backward traversal
- Easier deletion
#Head and Tail References
LinkedList stores:
Node<E> first;
Node<E> last;These references allow efficient insertion/removal at both ends.
#Adding Elements
LinkedList<Integer> list = new LinkedList<>();
list.add(10);
list.add(20);
list.add(30);#Accessing Elements
list.get(5);Can LinkedList jump directly to index 5? No. It must traverse.
Optimization Inside LinkedList
Java is smarter. If you need list.get(98) and the total size is 100, Java starts from the tail instead of the head. For list.get(2) it starts from the head.
if (index < size / 2)
start from head
else
start from tail#Insertion
Adding at the beginning
list.addFirst(100);Adding at the end
list.addLast(40); // O(1)Adding in the middle
Traversal is needed first.
list.add(5, 100);| Step | Cost |
|---|---|
| Traversal | O(n) |
| Insertion | O(1) |
| Total | O(n) |
#Deletion
| Operation | Complexity | Why |
|---|---|---|
list.removeFirst(); | O(1) | Pointers change |
list.removeLast(); | O(1) | Pointers change |
| Remove from middle | O(n) | Traversal needed |
#Why is Insertion Faster?
ArrayList — inserting at the beginning of A B C D needs shifting to get 100 A B C D. All elements move.
LinkedList — 100 → A → B → C → D. Only references change.
#Queue Operations
LinkedList implements Deque. Therefore these are available:
offer(), offerFirst(), offerLast(), poll(), pollFirst(), pollLast(), peek(), peekFirst(), peekLast()
#Stack Operations
LinkedList can also behave as a Stack with push(), pop() and peek().
LinkedList<Integer> stack = new LinkedList<>();
stack.push(10);
stack.push(20);
System.out.println(stack.pop());20#Null Values and Duplicates
Nulls are allowed:
list.add(null);
list.add(null);Duplicates are allowed:
list.add("Java");
list.add("Java");[Java, Java]#Thread Safety
#Internal Source Code (Simplified)
Adding last:
void linkLast(E e) {
Node<E> l = last;
Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
}Only references change.
#Memory Usage
Interview favourite. Each node stores data plus a previous and next reference. Compared to ArrayList, memory usage is higher.
| ArrayList | LinkedList |
|---|---|
A B C D | Prev A Next · Prev B Next · Prev C Next · Prev D Next |
Extra references consume additional memory.
#Cache Locality
- ArrayList —
A B C D Estored contiguously. CPU cache-friendly. - LinkedList — nodes are scattered in memory. Poor cache locality.
Hence iteration is generally slower than ArrayList. (Interview favourite.)
#ArrayList vs LinkedList
| Feature | ArrayList | LinkedList |
|---|---|---|
| Internal Structure | Dynamic Array | Doubly Linked List |
| Random Access | O(1) | O(n) |
| Insert at End | O(1)* | O(1) |
| Insert at Beginning | O(n) | O(1) |
| Remove at Beginning | O(n) | O(1) |
| Memory Usage | Lower | Higher |
| Cache Friendly | Yes | No |
| Implements Deque | No | Yes |
*Amortized O(1)
#When Should You Use LinkedList?
Use LinkedList when:
- Frequent insertions/removals at the beginning or end
- Queue implementation
- Deque implementation
- Stack implementation (though
ArrayDequeis generally preferred) - Sequential traversal
Avoid LinkedList when:
- Frequent random access
- Read-heavy applications
- Memory optimization is important
#Common Mistakes
- Using
LinkedListfor random access —list.get(90000);is slow. - Assuming insertion is always O(1). Wrong — finding the insertion position requires traversal, so the total complexity is O(n).
- Using
LinkedListinstead ofArrayListfor every List.ArrayListis generally the better default choice for most applications.
#Time Complexity
| Operation | Complexity |
|---|---|
| get(index) | O(n) |
| set(index) | O(n) |
| addLast() | O(1) |
| addFirst() | O(1) |
| add(index) | O(n) |
| removeFirst() | O(1) |
| removeLast() | O(1) |
| remove(index) | O(n) |
| contains() | O(n) |
| iteration | O(n) |
#Frequently Asked Interview Questions
Q1Why is LinkedList slower than ArrayList for reading?
Because it cannot directly access an index. It must traverse nodes one by one.
Q2Why is LinkedList faster for insertion?
Once the target position is reached, only node references (prev and next) need to be updated. No element shifting is required.
Q3Does LinkedList use a singly or doubly linked list?
Doubly linked list.
Q4Why does LinkedList implement Deque?
Because it supports efficient insertion and removal from both the front and the rear.
Q5Can LinkedList be used as a Queue?
Yes — methods include offer(), poll() and peek().
Q6Can LinkedList be used as a Stack?
Yes — methods include push(), pop() and peek(). However, ArrayDeque is generally recommended for stack implementations.
Q7Why does LinkedList consume more memory?
Each node stores the element plus two additional references (prev and next).
Q8How does get(index) work internally?
Java chooses the shorter traversal path:
- Starts from
firstif the index is in the first half. - Starts from
lastif the index is in the second half.
Q9Is LinkedList thread-safe?
No.
Q10Which is better: ArrayList or LinkedList?
There is no universal winner.
ArrayListis better for random access and read-heavy workloads.LinkedListis useful for frequent insertions/removals at the ends and for queue/deque operations.
#Chapter Summary
LinkedListis implemented as a doubly linked list.- Every element is stored in a separate
Node. - Nodes maintain references to both the previous and next nodes.
- Random access is O(n), while insertion/removal at the ends is O(1).
LinkedListuses more memory thanArrayListbecause of additional node references.- Poor cache locality makes iteration slower than
ArrayListin many real-world scenarios. LinkedListalso implements theDequeinterface, enabling queue and stack operations.