Skip to main content

Java Collections

ArrayList

Complete lesson for ArrayList using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with Java OOP and Collections where relevant.

L1

Basics — ArrayList

Section: Java Collections. ArrayList internals: grow policy, RandomAccess, complexity, and vs LinkedList.

A resizable array

  • ArrayList implements List, RandomAccess, Cloneable, Serializable. Backing store is an Object[].
  • size() is the number of elements. **Capacity** is the array length. When full, it grows (typically 1.5× in OpenJDK).
  • get(i) / set(i) are O(1). add(e) at the end is amortized O(1). add(i, e) / remove(i) are O(n) because elements shift.
import java.util.ArrayList;
import java.util.List;

public class ArrayListBasics {
    public static void main(String[] args) {
        List<String> cities = new ArrayList<>(4); // initial capacity
        cities.add("Pune");
        cities.add("Delhi");
        cities.add(1, "Mumbai");
        cities.remove("Delhi");
        System.out.println(cities.get(0));
        System.out.println(cities);
    }
}

ArrayList vs LinkedList

ArrayListLinkedList
StructureDynamic arrayDoubly linked nodes
get(i)O(1)O(n)
add at endAmortized O(1)O(1)
add/remove at frontO(n)O(1)
MemoryCompact arrayPer-node pointers + object header
LocalityExcellent (CPU cache)Poor
Implements DequeNoYes
Default choice for ListYesRarely

Common operations

  • ensureCapacity(n) avoids repeated growth if you know the size. trimToSize() shrinks the array to size.
  • remove(int) vs remove(Object): for ArrayList , remove(1) removes **index** 1. Use remove(Integer.valueOf(1)) to remove the value 1.
L2

Advanced — ArrayList

Growth, fail-fast, and interview mistakes

  • Growth copies the array (Arrays.copyOf). Adding n elements from capacity 0 is still amortized O(n).
  • Iterators and for-each are fail-fast (modCount). Use Iterator.remove or removeIf (Java 8).
  • ArrayList is not synchronized. Vector is the old synchronized list — prefer Collections.synchronizedList or a concurrent structure.
  • subList is a view: changes write through, and structural changes to the parent can invalidate the view.
  • Default initial capacity is 10 only after the first add in modern OpenJDK (empty list starts with a shared empty array).
L3

Tricky Interview Points

Q1) How does ArrayList grow?

Answer When size == capacity, it allocates a larger array (about 1.5×) and copies elements. add at the end is amortized O(1).

Q2) ArrayList vs LinkedList — which to pick?

Answer ArrayList almost always. Random access and cache locality win. Use LinkedList only if you truly need frequent end-to-end deque operations and already measured it — or just use ArrayDeque.

Q3) Why is get O(1)?

Answer Elements sit in a contiguous array. Index i is a single array load.

Q4) remove(1) on ArrayList<Integer>?

Answer Calls remove(int index), not remove(Object). Integer 1 as a value needs remove(Integer.valueOf(1)).

Q5) Is ArrayList synchronized?

Answer No. Concurrent add/get without external locking is unsafe.

Q6) What is RandomAccess?

Answer A marker interface telling algorithms that index access is cheap. ArrayList has it; LinkedList does not — binary search / some Collections methods choose different loops.

L4

Simple Programs

Capacity and Integer remove trap

import java.util.ArrayList;
import java.util.List;

public class ArrayListTraps {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>();
        nums.add(10);
        nums.add(20);
        nums.add(30);
        nums.remove(Integer.valueOf(20)); // value, not index
        System.out.println(nums);         // [10, 30]
        nums.remove(0);                   // index
        System.out.println(nums);         // [30]
    }
}
L5

Problem Solving Tricks

  • Pre-size with new ArrayList<>(expected) when you know n.
  • Prefer List.of(...) when the list never changes.
  • Use removeIf(predicate) instead of a manual iterator loop.
  • Never store a subList after structurally changing the parent.
L6

Practice Programs List

  1. Implement “remove all evens” three ways: index loop backward, Iterator, removeIf.
  2. Insert 100_000 elements, then get the middle — compare mentally to LinkedList.
  3. Show remove(1) vs remove(Integer.valueOf(1)) on List.
  4. Copy an array into an ArrayList with new ArrayList<>(List.of(...)) and then mutate the list.
  5. Trigger CME and then fix it.