Why ArrayList Middle Insert Is O(n)
Fast recall
Quick revision
Core answer
i in an ArrayList is O(n) because every element from i onward must shift one slot to the right (done via System.arraycopy). Appending at the end is O(1) amortized — unless the backing array is full, which triggers a resize (grow ~50% and copy), making that single add O(n).Whether you understand element shifting and amortized append cost
Thinking all ArrayList adds are O(1), or that LinkedList fully solves middle insertion
Explain System.arraycopy is a fast bulk memory move, so middle insert is O(n) but with a small constant
Interview-ready guide
Interview answer
Adding to the middle of an ArrayList is O(n) because of element shifting.
An ArrayList stores everything contiguously in an array, so when you insert at index i, every element from i to the end has to move one position to the right to make room. In the worst case — inserting at the front — that's n moves, so it's linear. Removing from the middle is the same idea in reverse: the elements after the gap shift left to close it.
Now, appending at the end is different. Most of the time it's O(1), because you just place the element in the next free slot. The exception is when the backing array is full.
Then ArrayList creates a new array about fifty percent larger and copies everything across, and that particular add is O(n). But because these resizes happen less and less often as the list grows, the average cost of an append is still O(1) — we call that amortized constant time. arraycopy, which is a fast native bulk memory move, so even though the Big-O is linear the constant factor is small.
Two practical tips: if you know roughly how many elements you'll add, pass an initial capacity to the constructor to avoid repeated resizes; and if you need cheap insertion at the front, don't loop add at index zero on an ArrayList because that's quadratic — use an ArrayDeque, which is O(1) at both ends.
And remember, switching to LinkedList doesn't fix middle insertion, because you still have to walk to the index first.
Why ArrayList Middle Insert Is O(n)
Direct Answer
Inserting at index i in an ArrayList is O(n) because every element from i onward must shift one slot to the right (done via System.arraycopy). Appending at the end is O(1) amortized — unless the backing array is full, which triggers a resize (grow ~50% and copy), making that single add O(n).
Common Mistakes & Pitfalls
- Thinking every add is O(1). Only end-appends are O(1) amortized; positional inserts are O(n).
- Front-inserting in a loop.
add(0, x)repeatedly is O(n^2) — useArrayDequeor append then reverse. - Ignoring resizes. Without pre-sizing, a big build does several full-array copies; pass an initial capacity.
- Believing LinkedList fixes it. LinkedList's middle insert is still O(n) because you traverse to the index first.
Check your understanding
Answer these without looking back at the article.
- What is System.arraycopy and how fast is it in practice?
- Would using a LinkedList solve the middle insert problem?
- What data structure should you use for a queue in Java?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.