ArrayList vs LinkedList
๐ Quick Reference
| Operation | ArrayList | LinkedList | Winner |
|---|---|---|---|
get(i) | O(1) | O(n) | ArrayList |
add(e) (end) | O(1)* | O(1) | Tie |
add(0, e) (front) | O(n) | O(1) | LinkedList |
add(i, e) (middle) | O(n) | O(n) | ArrayList** |
remove(0) | O(n) | O(1) | LinkedList |
remove(size-1) | O(1) | O(1) | Tie |
contains(e) | O(n) | O(n) | ArrayList** |
| Memory per element | ~4 bytes | ~24 bytes | ArrayList |
* Amortized (occasional resize) ** Better cache locality
๐ฎ Interactive Visualizer
Compare how ArrayList and LinkedList handle the same operations:
Loading visualizer...
- Random access (get) - see ArrayList's O(1) vs LinkedList's traversal
- Add at front - LinkedList just updates pointers
- Add at end - both are fast
- Add in middle - ArrayList shifts, LinkedList traverses then inserts
๐ง Internal Structure
ArrayList (Dynamic Array)
Contiguous memory block: โโโโโฌโโโโฌโโโโฌโโโโฌโโโโฌโโโโฌโโโโฌโโโโ โ A โ B โ C โ D โ E โ โ โ โ โโโโโดโโโโดโโโโดโโโโดโโโโดโโโโดโโโโดโโโโ 0 1 2 3 4 5 6 7 โ size=5, capacity=8 get(2): Direct calculation โ array[2] โ O(1) add("F"): array[5] = "F", size++ โ O(1) add(0, "Z"): Shift all right, then insert โ O(n)
LinkedList (Doubly-Linked)
Scattered nodes with pointers: โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ prev: โ โโโโโโ prev โโโโโโ prev โ โ data: A โ โ data: B โ โ data: C โ โ next โโโโโโ next โโโโโโ next: โ โ โโโโโโโโโโโ โโโโโโโโโโโ โโโโโโโโโโโ โ โ head tail get(2): headโnextโnext โ O(n) addFirst("Z"): Create node, update head pointer โ O(1) addLast("D"): Create node, update tail pointer โ O(1)
๐ Detailed Complexity Analysis
Time Complexity
| Operation | ArrayList | LinkedList | Notes |
|---|---|---|---|
get(index) | O(1) | O(n) | AL: direct index; LL: traverse |
set(index, e) | O(1) | O(n) | Same as get |
add(e) | O(1)* | O(1) | AL: amortized; LL: has tail |
add(index, e) | O(n) | O(n) | AL: shift; LL: traverse + insert |
addFirst(e) | O(n) | O(1) | AL: shift all; LL: pointer update |
remove(index) | O(n) | O(n) | AL: shift; LL: traverse |
removeFirst() | O(n) | O(1) | AL: shift all; LL: pointer update |
removeLast() | O(1) | O(1) | Both have tail/size info |
contains(e) | O(n) | O(n) | AL faster (cache) |
indexOf(e) | O(n) | O(n) | AL faster (cache) |
clear() | O(n) | O(n) | Help GC |
size() | O(1) | O(1) | Both cache size |
* Amortized O(1), worst case O(n) during resize
Space Complexity
| Aspect | ArrayList | LinkedList |
|---|---|---|
| Element storage | 4-8 bytes/ref | 24+ bytes/node |
| Overhead (empty) | ~88 bytes | ~48 bytes |
| Overhead (1000 elem) | ~4-16 KB | ~24 KB |
| Memory locality | Contiguous | Scattered |
| Cache performance | Excellent | Poor |
โ When to Use Which
Choose ArrayList When
JAVA(19 lines)CodeLoading syntax highlighter...
Choose LinkedList When
JAVA(22 lines)CodeLoading syntax highlighter...
๐ Common Operations Comparison
Adding Elements
JAVA(11 lines)CodeLoading syntax highlighter...
Removing Elements
JAVA(11 lines)CodeLoading syntax highlighter...
Iteration Performance
JAVA(20 lines)CodeLoading syntax highlighter...
๐งฉ Real-World Patterns
Pattern 1: Stack
JAVA(5 lines)CodeLoading syntax highlighter...
Pattern 2: Queue
JAVA(7 lines)CodeLoading syntax highlighter...
Pattern 3: Frequent Middle Insertions
JAVA(5 lines)CodeLoading syntax highlighter...
Pattern 4: LRU Cache
JAVA(16 lines)CodeLoading syntax highlighter...
โ ๏ธ Common Pitfalls
1. Indexed Loop on LinkedList
JAVA(9 lines)CodeLoading syntax highlighter...
2. Using LinkedList as General-Purpose List
JAVA(7 lines)CodeLoading syntax highlighter...
3. Not Pre-sizing ArrayList
JAVA(8 lines)CodeLoading syntax highlighter...
4. Assuming add() is Always Fast
JAVA(6 lines)CodeLoading syntax highlighter...
๐ฏ Interview Practice
Test your ArrayList vs LinkedList knowledge with 10 curated interview questions:
๐ค List Comparison Interview Mode - Coming Soon
๐ค Interview Tips
"LinkedList when you need O(1) insertions/removals at the front (queue operations), or when using Iterator.remove() frequently. In practice, ArrayList is better 95% of the time due to cache locality and lower memory overhead.
"ArrayList stores elements contiguously in memory, benefiting from CPU cache prefetching. LinkedList nodes are scattered in memory, causing cache misses on every access.
"ArrayList: ~4-8 bytes per reference (just the array slot). LinkedList: ~24 bytes per node (object header, prev pointer, next pointer, data reference). For large lists, ArrayList uses 3-6x less memory.
"ArrayDeque is usually better for queues - it's faster and uses less memory. LinkedList is only useful if you need null elements (ArrayDeque doesn't allow null) or need to remove elements from the middle during iteration.
๐ Series Navigation
ListComparisonVisualizer from @tomaszjarosz/react-visualizers