ArrayList Internal Resizing Mechanism in Java
Fast recall
Quick revision
Core answer
ArrayList needs more room, it allocates a larger backing array and copies existing references, so that particular append is O(n) while repeated appends are amortized O(1). Current OpenJDK commonly grows by about 50% for ordinary sizes, but the Java API does not guarantee an exact growth factor or expose capacity as part of the List contract.Deep understanding of ArrayList's internal array mechanics and the concept of amortized time complexity
Believing ArrayList doubles its capacity like a default Vector commonly does — ArrayList currently grows by about 50 percent for ordinary sizes (1.5x), not 100 percent
Mention using the ArrayList constructor with initial capacity when you know the size upfront to avoid resize overhead during bulk loading
Interview-ready guide
Interview answer
ArrayList uses a fixed-length backing array. When an append needs more capacity, it allocates a larger array and copies the element references. That individual append is O(n), but because growth leaves spare capacity, many appends together are amortized O(1).
In current OpenJDK, ordinary growth is often about 50 percent, but that formula is an implementation detail. A default-constructed list also allocates lazily; capacity 10 is the usual first capacity after the first element is added, not an array allocated by the constructor. If I know the final count, I pre-size the list or use ensureCapacity to reduce copies.
ArrayList Internal Resizing Mechanism in Java
Direct Answer
When an ArrayList needs more room, it allocates a larger backing array and copies existing references, so that particular append is O(n) while repeated appends are amortized O(1). Current OpenJDK commonly grows by about 50% for ordinary sizes, but the Java API does not guarantee an exact growth factor or expose capacity as part of the List contract.
Code Example
import java.util.ArrayList;
import java.util.List;
public class ArrayListResizeDemo {
public static void main(String[] args) {
// Default initial capacity is 10
List<String> orders = new ArrayList<>();
// Add 10 elements - no resize yet
for (int i = 1; i <= 10; i++) orders.add("Order-" + i);
// 11th element triggers resize: 10 -> 15 (10 + 10/2)
orders.add("Order-11");
// Fill to 15 - no resize
for (int i = 12; i <= 15; i++) orders.add("Order-" + i);
// 16th element triggers resize: 15 -> 22 (15 + 15/2)
orders.add("Order-16");
// If you know the size upfront, pre-size to avoid resizes
List<String> bulk = new ArrayList<>(1000);
for (int i = 0; i < 1000; i++) bulk.add("Order-" + i); // no resizes
}
}
Common Mistakes & Pitfalls
- Saying
ArrayListdoubles capacity: Freshers assume it doubles likeVector(2x), butArrayListcurrently grows by about 50 percent for ordinary sizes —an implementation-specific growth calculation, which equalsoldCapacitytimes 1.5. - Claiming
addis always O(1): The correct term is amortized O(1). An individualaddthat triggers a resize is O(n) because all elements get copied, but resizes are rare enough that the average stays constant. - Ignoring initial capacity in tight loops: Building large lists inside a hot method (like a controller handling thousands of requests per second) without setting initial capacity makes every request pay the resize penalty.
Check your understanding
Answer these without looking back at the article.
- What is amortized O(1) and why does it apply to ArrayList add?
- How is ArrayList resizing different from Vector resizing?
- What does trimToSize() do on an ArrayList?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.