Java ArrayList: Internal Working, Dynamic Resizing and Methods

ArrayList is the most frequently used collection class in Java. It implements the List interface, backed internally by a dynamically resizing array allocated on the Heap.

How ArrayList Works Internally (Under the Hood)

When you instantiate ArrayList<String> list = new ArrayList<>();, Java creates a reference to an empty internal array: elementData = {}.

  • First Addition: Calling list.add("Java") expands the internal array to the default capacity of 10.
  • Capacity Exhaustion & 1.5x Growth: When the 11th element is added, the internal array is full. Java calculates:
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 10 + 5 = 15!
    A new 15-element array is allocated on the Heap, elements are copied via native System.arraycopy(), and the old array is reclaimed by the Garbage Collector.

Practical Code Demonstration

import java.util.ArrayList;
import java.util.Collections;

public class ArrayListDemo {
    public static void main(String[] args) {
        // 1. Instantiating a generic ArrayList of Strings
        ArrayList<String> frameworks = new ArrayList<>();

        // 2. Adding elements (O(1) amortized time)
        frameworks.add("Spring Boot");
        frameworks.add("Hibernate");
        frameworks.add("Micronaut");
        frameworks.add("Quarkus");

        // 3. Fast random access by index (O(1) time)
        System.out.println("First framework: " + frameworks.get(0)); // Spring Boot

        // 4. Updating an element
        frameworks.set(2, "Jakarta EE");

        // 5. Removing an element
        frameworks.remove("Quarkus");

        // 6. Checking existence and size
        System.out.println("Contains Hibernate? " + frameworks.contains("Hibernate")); // true
        System.out.println("Current Size: " + frameworks.size()); // 3

        // 7. Sorting using Collections utility
        Collections.sort(frameworks);
        System.out.println("Sorted List: " + frameworks);
    }
}

Time Complexity Matrix

Operation Time Complexity Underlying Mechanism
get(index)O(1) ConstantDirect memory pointer math: base + index * size
add(element)O(1) AmortizedAppends to end of internal array
add(index, element)O(n) LinearShifts all subsequent elements to the right
remove(index)O(n) LinearShifts all subsequent elements to the left
contains(object)O(n) LinearSequential linear search using equals()

Next Step

Now let us explore LinkedList, its doubly-linked node architecture, and when it outperforms ArrayList. Proceed to: Java LinkedList Class →

Frequently Asked Questions (FAQ)

Q1. How does ArrayList dynamically resize itself when full in Java?
When an ArrayList exceeds its capacity, the JVM allocates a new internal array on the Heap with 1.5 times the previous capacity (newCapacity = oldCapacity + (oldCapacity >> 1)), copies existing elements over using System.arraycopy(), and discards the old array.
Q2. What is the initial default capacity of an ArrayList?
When instantiated with the default no-arg constructor (new ArrayList<>()), the initial capacity is 0 until the very first element is added, at which point the internal array expands to a default capacity of 10.
Q3. Is ArrayList thread-safe in Java?
No! ArrayList is not synchronized. If multiple threads modify an ArrayList concurrently, it throws ConcurrentModificationException or corrupts internal state. For thread safety, use Collections.synchronizedList() or CopyOnWriteArrayList.

Explore Related Java Tutorials

Accelerate your Java mastery by studying these tightly connected core tutorials:

Java LinkedList →

Doubly linked list comparison.

Java Arrays Basics →

Fixed-size array foundation.

Java Iterators →

Iterating through lists.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Stumbleupon Share on Tumblr Share on Reddit Share on Diggit

You may also like this!