Introduction
Arrays have a fixed size—once created, they cannot grow or shrink. This limitation makes arrays awkward when you don't know how many elements you'll need or when the collection changes frequently. The ArrayList class solves this problem by providing a resizable collection.
Topic 4.8 introduces the ArrayList class and its essential methods. Unlike arrays, ArrayLists can grow and shrink dynamically, and they provide convenient methods for adding, removing, and accessing elements. Understanding ArrayList operations is critical—they appear extensively on the AP exam, particularly in the ArrayList free-response question.
What is an ArrayList?
An ArrayList object is mutable in size and contains object references. While arrays have fixed length, ArrayLists automatically resize as you add or remove elements.
Key differences from arrays:
| Arrays | ArrayLists |
|---|---|
| Fixed size | Dynamic size |
| Can hold primitives or objects | Can only hold objects |
| Use length attribute | Use size() method |
| Use [] syntax | Use method calls |
| Create with new int[5] | Create with new ArrayList<Integer>() |
Creating ArrayLists
The ArrayList constructor ArrayList() constructs an empty list.
ArrayList<String> names = new ArrayList<String>();
// Creates empty ArrayList that will hold StringsGeneric Type Syntax
Java allows the generic type ArrayList
The angle brackets <> specify what type of objects the ArrayList will store:
ArrayList<Integer> numbers = new ArrayList<Integer>();
ArrayList<String> words = new ArrayList<String>();
ArrayList<Double> prices = new ArrayList<Double>();When ArrayList
Why use generics? ArrayList
// Without generics (not recommended)
ArrayList list = new ArrayList();
list.add("Hello");
list.add(42); // No error - can add anything
String s = (String) list.get(1); // Runtime error!
// With generics (recommended)
ArrayList<String> list = new ArrayList<String>();
list.add("Hello");
list.add(42); // COMPILER ERROR - caught immediately
Import Statement
The ArrayList class is part of the java.util package. An import statement must be used to make this class available for use in the program.
import java.util.ArrayList;
public class MyProgram
{
public static void main(String[] args)
{
ArrayList<Integer> numbers = new ArrayList<Integer>();
}
}ArrayList Methods
The following ArrayList methods are part of the Java Quick Reference and appear frequently on the AP exam.
size() Method
int size() — returns the number of elements in the list.
ArrayList<String> names = new ArrayList<String>();
System.out.println(names.size()); // 0 (empty)
names.add("Alice");
names.add("Bob");
System.out.println(names.size()); // 2
Important: Arrays use length attribute; ArrayLists use size() method:
int[] arr = new int[5];
arr.length; // 5 (no parentheses)
ArrayList<Integer> list = new ArrayList<Integer>();
list.size(); // 0 (method call with parentheses)
add(E obj) Method
boolean add(E obj) — appends obj to end of list; returns true.
ArrayList<Integer> scores = new ArrayList<Integer>();
scores.add(85); // [85]
scores.add(92); // [85, 92]
scores.add(78); // [85, 92, 78]
The method always returns true, indicating the add was successful:
boolean result = scores.add(88); // result is trueadd(int index, E obj) Method
void add(int index, E obj) — inserts obj at position index (0 <= index <= size), moving elements at position index and higher to the right (adds 1 to their indices) and adds 1 to size.
ArrayList<String> colors = new ArrayList<String>();
colors.add("red"); // ["red"]
colors.add("blue"); // ["red", "blue"]
colors.add(1, "green"); // ["red", "green", "blue"]
When inserting at index 1, "blue" shifts from index 1 to index 2.
Valid indices: 0 through size() (inclusive). You can insert at the end using index = size():
colors.add(colors.size(), "yellow"); // Adds to endget(int index) Method
E get(int index) — returns the element at position index in the list.
ArrayList<String> fruits = new ArrayList<String>();
fruits.add("apple");
fruits.add("banana");
fruits.add("cherry");
System.out.println(fruits.get(0)); // "apple"
System.out.println(fruits.get(1)); // "banana"
System.out.println(fruits.get(2)); // "cherry"
set(int index, E obj) Method
E set(int index, E obj) — replaces the element at position index with obj; returns the element formerly at position index.
ArrayList<Integer> values = new ArrayList<Integer>();
values.add(10);
values.add(20);
values.add(30);
int oldValue = values.set(1, 99); // Replace 20 with 99
// oldValue is 20
// ArrayList is now [10, 99, 30]
Note: set() replaces an existing element—it doesn't insert. The index must already exist.
remove(int index) Method
E remove(int index) — removes element from position index, moving elements at position index + 1 and higher to the left (subtracts 1 from their indices) and subtracts 1 from size; returns the element formerly at position index.
ArrayList<String> names = new ArrayList<String>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
// ["Alice", "Bob", "Charlie"]
String removed = names.remove(1); // Remove "Bob"
// removed is "Bob"
// ArrayList is now ["Alice", "Charlie"]
// "Charlie" shifted from index 2 to index 1
Valid Index Range
The indices for an ArrayList start at 0 and end at the number of elements - 1.
For an ArrayList with elements:
- Valid indices:
- Invalid indices: or higher, any negative number
Accessing invalid indices throws IndexOutOfBoundsException:
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(10);
nums.add(20);
// Valid indices: 0, 1
nums.get(0); // OK: 10
nums.get(1); // OK: 20
nums.get(2); // ERROR: IndexOutOfBoundsException
nums.get(-1); // ERROR: IndexOutOfBoundsExceptionWorking with ArrayLists
Example 1: Building and Displaying
import java.util.ArrayList;
public class ListDemo
{
public static void main(String[] args)
{
ArrayList<String> tasks = new ArrayList<String>();
tasks.add("Study");
tasks.add("Exercise");
tasks.add("Read");
System.out.println("Tasks: " + tasks.size());
for (int i = 0; i < tasks.size(); i++)
{
System.out.println(tasks.get(i));
}
}
}
Example 2: Modifying Elements
ArrayList<Integer> scores = new ArrayList<Integer>();
scores.add(85);
scores.add(90);
scores.add(78);
// Curve all scores by 5 points
for (int i = 0; i < scores.size(); i++)
{
int curved = scores.get(i) + 5;
scores.set(i, curved);
}
// [90, 95, 83]
Example 3: Inserting and Removing
list.add("A");
list.add("C");
list.add(1, "B"); // ["A", "B", "C"]
list.remove(2); // ["A", "B"]
list.add("D"); // ["A", "B", "D"]
ArrayLists vs Arrays
// Array approach - fixed size
int[] scores = new int[3];
scores[0] = 85;
scores[1] = 92;
scores[2] = 78;
// Can't easily add a 4th score
// ArrayList approach - dynamic size
ArrayList<Integer> scoreList = new ArrayList<Integer>();
scoreList.add(85);
scoreList.add(92);
scoreList.add(78);
scoreList.add(88); // Easy to add more!
Common Mistakes
Mistake 1: Forgetting import statement
// WRONG - won't compile without import
ArrayList<String> names = new ArrayList<String>();Mistake 2: Using primitives instead of wrapper classes
// WRONG - can't use primitive types
ArrayList<int> numbers = new ArrayList<int>();
// CORRECT - use wrapper class
ArrayList<Integer> numbers = new ArrayList<Integer>();Mistake 3: Using array syntax
ArrayList<String> names = new ArrayList<String>();
names.add("Alice");
// WRONG - ArrayList doesn't use []
String s = names[0];
// CORRECT - use get()
String s = names.get(0);
Mistake 4: Confusing set() and add()
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.set(0, 10); // WRONG - index 0 doesn't exist yet
nums.add(10); // CORRECT - adds first element
nums.set(0, 20); // Now OK - replaces 10 with 20