AP CS A AP CSP Tutoring Blog Request a Session
← Back to Blog
AP CS A

AP CS A Arrays and ArrayLists: The Complete Guide

By Namrata Poladia April 21, 2026

Arrays and ArrayLists appear on every AP CS A exam, every year. At least one of the four free-response questions is dedicated to array or ArrayList manipulation, and array traversal shows up constantly in the multiple-choice section. If you want to score well on AP CS A, this is the topic you cannot afford to be shaky on.

This guide covers everything the exam tests: how arrays and ArrayLists work, how to traverse and manipulate them, the algorithms you need to know cold, the mistakes that cost students points, and the FRQ patterns that repeat year after year.

Part 1: Arrays

What an array is

An array is a fixed-size, ordered collection of elements of the same type. "Fixed-size" is the key phrase: once you create an array, its length cannot change. If you declare an array of 10 integers, it will always hold exactly 10 integers.

Arrays in Java are zero-indexed: the first element is at index 0, the last element is at index length - 1. This is different from everyday counting, and off-by-one errors from forgetting this are among the most common mistakes on the exam.

Declaring and initializing arrays

There are two ways to create an array in Java.

Option 1: declare with a size. This creates the array and fills it with default values (0 for int, 0.0 for double, false for boolean, null for objects).

int[] scores = new int[5];       // [0, 0, 0, 0, 0]
double[] prices = new double[3]; // [0.0, 0.0, 0.0]
String[] names = new String[4];  // [null, null, null, null]

Option 2: initialize with values. The size is inferred from the number of values provided.

int[] scores = {92, 85, 78, 91, 88};
String[] days = {"Mon", "Tue", "Wed", "Thu", "Fri"};

Accessing and modifying elements

Use bracket notation with an index to read or write a specific element.

int[] scores = {92, 85, 78, 91, 88};

System.out.println(scores[0]); // 92 (first element)
System.out.println(scores[4]); // 88 (last element)

scores[2] = 95; // changes 78 to 95
// scores is now {92, 85, 95, 91, 88}

Accessing an index that doesn't exist throws an ArrayIndexOutOfBoundsException at runtime. Accessing scores[5] on a 5-element array (valid indices 0–4) is one of the most common runtime errors on the exam.

The length property

array.length gives the number of elements. Note: it's a property, not a method, so there are no parentheses.

int[] scores = {92, 85, 78, 91, 88};
System.out.println(scores.length); // 5
System.out.println(scores[scores.length - 1]); // 88 (last element)

Using scores.length instead of a hardcoded number is important: it keeps your code correct even if the array size changes.

Traversing arrays with a for loop

The standard traversal pattern iterates from index 0 to length - 1.

int[] scores = {92, 85, 78, 91, 88};

for (int i = 0; i < scores.length; i++) {
    System.out.println(scores[i]);
}

This gives you both the index (i) and the value (scores[i]). Use a standard for loop whenever you need the index, for example to compare adjacent elements, modify elements in place, or traverse in reverse.

Traversing with an enhanced for loop

The enhanced for loop (also called a "for-each" loop) iterates through values directly, without an index variable.

int[] scores = {92, 85, 78, 91, 88};

for (int score : scores) {
    System.out.println(score);
}

This is cleaner when you only need the value, but it has two important limitations:

  • You cannot modify the array through the loop variable. Assigning to score inside the loop does not change the array.
  • You don't have access to the index. If you need to know where in the array you are, use a standard for loop.

Essential array algorithms

These are the patterns that appear most often on the exam, both in MCQ and FRQ. Know each one well enough to write it from memory.

Sum and average:

public static double average(int[] arr) {
    int sum = 0;
    for (int val : arr) {
        sum += val;
    }
    return (double) sum / arr.length;
}

The cast to double before dividing is critical. Without it, you get integer division and lose the decimal portion.

Find the minimum (or maximum):

public static int findMin(int[] arr) {
    int min = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
    }
    return min;
}

Start min at arr[0], not at 0 or Integer.MAX_VALUE, unless the problem specifically requires it. Starting at arr[0] is simpler and avoids edge cases. Begin the loop at index 1 since you've already accounted for index 0.

Linear search:

public static int indexOf(int[] arr, int target) {
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == target) {
            return i;
        }
    }
    return -1; // target not found
}

Returning -1 when the target isn't found is the standard convention. The exam expects this pattern.

Count elements matching a condition:

public static int countEvens(int[] arr) {
    int count = 0;
    for (int val : arr) {
        if (val % 2 == 0) {
            count++;
        }
    }
    return count;
}

Reverse traversal:

for (int i = arr.length - 1; i >= 0; i--) {
    System.out.println(arr[i]);
}

Start at arr.length - 1 (the last index) and decrement until i >= 0. The condition is >= 0, not > 0, because index 0 is a valid element.

Shifting elements left (to remove an element):

// Remove the element at index k by shifting everything after it left
for (int i = k; i < arr.length - 1; i++) {
    arr[i] = arr[i + 1];
}

After this loop, the last element is duplicated (both arr[arr.length - 2] and arr[arr.length - 1] hold the same value). Arrays can't shrink, so you'd typically track a logical size separately or switch to an ArrayList.

Part 2: ArrayLists

What an ArrayList is

An ArrayList is a resizable list that can grow and shrink dynamically. Unlike an array, you don't have to know the size in advance. Elements can be added or removed at any time, and the ArrayList adjusts its size automatically.

ArrayLists can only hold objects, not primitives. To store integers, use Integer (the wrapper class); Java automatically converts between int and Integer through autoboxing and unboxing.

Importing and declaring an ArrayList

import java.util.ArrayList;

ArrayList<Integer> scores = new ArrayList<Integer>();
ArrayList<String> names = new ArrayList<String>();

The type goes inside angle brackets. On the AP exam, you're expected to include the import statement when writing code that uses ArrayList.

Essential ArrayList methods

Method What It Does Example
add(value)Appends value to the endlist.add(42)
add(index, value)Inserts value at index, shifting elements rightlist.add(2, 99)
get(index)Returns the element at indexlist.get(0)
set(index, value)Replaces the element at index with value, returns old valuelist.set(1, 77)
remove(index)Removes and returns the element at index, shifting elements leftlist.remove(3)
size()Returns the number of elementslist.size()

Note that ArrayList uses size(), not length. Mixing these up is a very common exam mistake.

Traversing an ArrayList

Both loop styles work. Use a standard for loop when you need the index; use an enhanced for loop when you only need the value.

ArrayList<Integer> scores = new ArrayList<Integer>();
scores.add(92);
scores.add(85);
scores.add(78);

// Standard for loop
for (int i = 0; i < scores.size(); i++) {
    System.out.println(scores.get(i));
}

// Enhanced for loop
for (int score : scores) {
    System.out.println(score);
}

Removing elements during traversal

This is one of the most tested ArrayList patterns on the exam. Removing an element during a forward traversal shifts all subsequent elements left by one, causing the loop to skip the element that moved into the removed element's position.

The wrong way (skips elements):

// BUG: skips elements after each removal
for (int i = 0; i < list.size(); i++) {
    if (list.get(i) < 0) {
        list.remove(i); // element at i+1 shifts to i, then i++ skips it
    }
}

Fix 1: iterate from back to front. Removing from the end doesn't affect earlier indices.

for (int i = list.size() - 1; i >= 0; i--) {
    if (list.get(i) < 0) {
        list.remove(i);
    }
}

Fix 2: decrement the index after removal.

for (int i = 0; i < list.size(); i++) {
    if (list.get(i) < 0) {
        list.remove(i);
        i--; // re-check the same index after the shift
    }
}

Either fix works. The backwards traversal (Fix 1) is generally cleaner and less error-prone.

Part 3: Arrays vs. ArrayLists

Array ArrayList
SizeFixed at creationDynamic, grows and shrinks
Element typesPrimitives or objectsObjects only (use wrapper classes)
Access syntaxarr[i]list.get(i)
Length/sizearr.length (property)list.size() (method)
Add elementsNot possible after creationlist.add(value)
Remove elementsManual shifting requiredlist.remove(index)
When to useSize is known and fixedSize varies or elements are added/removed

On FRQs, the question will tell you whether to use an array or an ArrayList. Read the method signature carefully: if the parameter is int[], use array syntax; if it's ArrayList<Integer>, use ArrayList methods.

Part 4: 2D Arrays

A 2D array is an array of arrays. Think of it as a table with rows and columns.

Declaration and initialization

int[][] grid = new int[3][4]; // 3 rows, 4 columns, all zeros

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

Dimensions

  • matrix.length is the number of rows (3 in the example above).
  • matrix[0].length is the number of columns (3 in the example above).

Mixing up rows and columns is one of the most common 2D array errors on the exam.

Row-major traversal (left to right, top to bottom)

for (int row = 0; row < matrix.length; row++) {
    for (int col = 0; col < matrix[row].length; col++) {
        System.out.print(matrix[row][col] + " ");
    }
    System.out.println();
}

Column-major traversal (top to bottom, left to right)

for (int col = 0; col < matrix[0].length; col++) {
    for (int row = 0; row < matrix.length; row++) {
        System.out.print(matrix[row][col] + " ");
    }
    System.out.println();
}

Swap the loop order to change the traversal direction. The inner loop variable changes fastest; the outer loop variable changes slowest.

Common 2D array algorithms

Sum of all elements:

int total = 0;
for (int[] row : matrix) {
    for (int val : row) {
        total += val;
    }
}

Find the largest value:

int max = matrix[0][0];
for (int[] row : matrix) {
    for (int val : row) {
        if (val > max) {
            max = val;
        }
    }
}

Row sums (sum each row independently):

for (int row = 0; row < matrix.length; row++) {
    int rowSum = 0;
    for (int col = 0; col < matrix[row].length; col++) {
        rowSum += matrix[row][col];
    }
    System.out.println("Row " + row + " sum: " + rowSum);
}

Part 5: Common Exam Mistakes

These are the specific errors that cost students points most often on the array and ArrayList portions of the exam.

  1. Using arr.length() instead of arr.length. Arrays use a property, not a method. arr.length() is a compile error. arr.length is correct. (Strings use .length() with parentheses, which makes this confusion understandable but still wrong.)
  2. Using list.length instead of list.size(). ArrayLists use a method. list.length doesn't exist. list.size() is correct.
  3. Off-by-one in the loop bound. for (int i = 0; i <= arr.length; i++) will throw ArrayIndexOutOfBoundsException on the last iteration because index arr.length doesn't exist. The correct bound is i < arr.length.
  4. Modifying array elements through an enhanced for loop variable. for (int val : arr) { val = 0; } does not change the array. val is a copy of the element. To modify elements in place, use a standard for loop with arr[i] = 0.
  5. Skipping elements when removing from an ArrayList during a forward traversal. After list.remove(i), the element at index i+1 shifts to index i. If you then increment i, you skip it. Iterate backwards or decrement i after each removal.
  6. Swapping rows and columns in a 2D array. matrix[row][col], not matrix[col][row]. The first index is always the row.
  7. Using arr.length instead of arr[0].length for the number of columns in a 2D array. matrix.length is the number of rows. matrix[0].length is the number of columns in the first row.
  8. Forgetting to initialize a result variable before a loop. Declaring int sum; and then using sum inside a loop without assigning it a value first is a compile error in Java. Always initialize: int sum = 0;.

Part 6: FRQ Patterns to Know

The College Board uses a small set of recurring FRQ patterns for arrays and ArrayLists. Recognizing the pattern quickly lets you start writing code immediately instead of spending time figuring out the approach.

Pattern What It Asks Key Technique
Filter and collectReturn a new array or ArrayList containing only elements that meet a conditionBuild a new ArrayList during traversal; convert to array if required
In-place removalRemove all elements from an ArrayList that meet a conditionTraverse backwards; call remove(i)
Search and return indexFind the first (or last) element matching a condition; return its index or -1Linear search with early return; return -1 after the loop
Accumulate and computeCalculate a sum, count, average, or running total across an arrayInitialize accumulator before loop; return after loop
Find min/max with indexReturn the index of the minimum or maximum element, not the value itselfTrack both the best value and the index where it was found
2D row/column operationProcess all elements in a specific row or column; compute row sums, column averagesFix one loop variable, iterate the other; pick traversal order carefully
Shift and insertInsert a value into a specific position by shifting elementsShift right-to-left before inserting; shift left-to-right for removal

The filter-and-collect pattern in detail

This pattern comes up frequently enough to deserve its own example. The task: given an array of integers, return a new array containing only the positive values.

public static int[] positiveValues(int[] arr) {
    // First pass: count how many positives there are
    int count = 0;
    for (int val : arr) {
        if (val > 0) {
            count++;
        }
    }

    // Allocate result array of exactly the right size
    int[] result = new int[count];

    // Second pass: fill result
    int index = 0;
    for (int val : arr) {
        if (val > 0) {
            result[index] = val;
            index++;
        }
    }
    return result;
}

When the return type is an ArrayList instead of an array, the approach is simpler: just add() matching elements to a new ArrayList during a single pass.

public static ArrayList<Integer> positiveValues(int[] arr) {
    ArrayList<Integer> result = new ArrayList<Integer>();
    for (int val : arr) {
        if (val > 0) {
            result.add(val);
        }
    }
    return result;
}

Quick Reference: Array vs. ArrayList Syntax

Operation Array ArrayList
Declareint[] arr = new int[n];ArrayList<Integer> list = new ArrayList<Integer>();
Get length/sizearr.lengthlist.size()
Read elementarr[i]list.get(i)
Write elementarr[i] = val;list.set(i, val);
Add to endNot possiblelist.add(val);
Remove by indexManual shift requiredlist.remove(i);
Standard for loopfor (int i = 0; i < arr.length; i++)for (int i = 0; i < list.size(); i++)
Enhanced for loopfor (int val : arr)for (int val : list)

Ready to Practice with an Expert?

Arrays and ArrayLists are skills that improve fastest with feedback on real code, not just reading examples. ExamReadyUSA's 4-week AP CS A Crash Course includes dedicated sessions on arrays, ArrayLists, and 2D arrays, with graded FRQ practice and line-by-line feedback from Namrata Poladia, a College Board AP Reader. Groups are capped at 5 students so every question gets answered.