# AP® Computer Science A 4.10 Implementing ArrayList Algorithms

Source: https://lockincs.com/ap-csa/unit-4/4-10-implementing-arraylist-algorithms/  
Last reviewed against the College Board Course and Exam Description (CED): 2026-11-12  
CED codes: 4.10.A, 4.10.A.1, 4.10.A.2

Standard ArrayList algorithms are traversals with a job: find a minimum or maximum, total the values, test a property, compare neighbors, move elements or insert and delete them. Some algorithms traverse two String, array or ArrayList objects at the same time. On the AP® exam you write these algorithms and trace what they produce.

## What you will learn

- 4.10.A Develop code for standard and original algorithms that involve ArrayList objects, and determine the result of these algorithms.

## 1\. Minimum, maximum, sum and average

An ArrayList algorithm is a traversal with a purpose. For a minimum or maximum, keep the best value seen so far and compare every element with it 4.10.A.1. For a sum, add each element to a running total; for an average, divide that total by `size()` using `double` division 4.10.A.1.

```
ArrayList<Integer> temps = new ArrayList<Integer>();
temps.add(-4);
temps.add(-9);
temps.add(-1);
temps.add(-6);

int max = temps.get(0);
int min = temps.get(0);
int sum = 0;
for (int t : temps)
{
    if (t > max)
    {
        max = t;
    }
    if (t < min)
    {
        min = t;
    }
    sum += t;
}
double avg = (double) sum / temps.size();
System.out.println("max " + max + ", min " + min);
System.out.println("average " + avg);
```

Output:

```
max -1, min -9
average -5.0
```

Watch out: if `max` started at 0, it would stay 0 for this all-negative list. Seed with the first element. Also, `sum / temps.size()` with two `int` values drops the decimal part.

## 2\. Property checks: at least one, all, and how many

Three algorithms ask a yes/no question about each element 4.10.A.1:

| Question | Variable | When to stop early |
| --- | --- | --- |
| Does at least one element have the property? | `boolean` | Return `true` at the first match |
| Do all elements have the property? | `boolean` | Return `false` at the first failure |
| How many elements have the property? | `int` counter | Never: visit every element |

```
public static boolean anyOver(ArrayList<Integer> scores, int limit)
{
    for (int s : scores)
    {
        if (s > limit)
        {
            return true;
        }
    }
    return false;
}

public static boolean allPassing(ArrayList<Integer> scores)
{
    for (int s : scores)
    {
        if (s < 60)
        {
            return false;
        }
    }
    return true;
}

public static int countEven(ArrayList<Integer> scores)
{
    int count = 0;
    for (int s : scores)
    {
        if (s % 2 == 0)
        {
            count++;
        }
    }
    return count;
}

ArrayList<Integer> scores = new ArrayList<Integer>();
scores.add(72);
scores.add(95);
scores.add(58);
scores.add(80);
System.out.println(anyOver(scores, 90));
System.out.println(allPassing(scores));
System.out.println(countEven(scores));
```

Output:

```
true
false
3
```

Watch out: putting `else return true;` inside the loop of `allPassing` makes the method decide after looking at only one element.

## 3\. Consecutive pairs and duplicates

To compare each element with its neighbor, visit all consecutive pairs: `get(i)` and `get(i + 1)`. The loop must stop at `size() - 1` so that `i + 1` is still a valid index 4.10.A.1.

To find duplicates, compare every element with every element after it, using nested loops 4.10.A.1. Use `equals` for objects such as `String`.

```
ArrayList<String> playlist = new ArrayList<String>();
playlist.add("Rain");
playlist.add("Echo");
playlist.add("Rain");
playlist.add("Glow");

int changes = 0;
for (int i = 0; i < playlist.size() - 1; i++)
{
    if (playlist.get(i).compareTo(playlist.get(i + 1)) > 0)
    {
        changes++;
    }
}
System.out.println("Out-of-order pairs: " + changes);

boolean hasDuplicate = false;
for (int i = 0; i < playlist.size(); i++)
{
    for (int j = i + 1; j < playlist.size(); j++)
    {
        if (playlist.get(i).equals(playlist.get(j)))
        {
            hasDuplicate = true;
        }
    }
}
System.out.println("Duplicate: " + hasDuplicate);
```

Output:

```
Out-of-order pairs: 2
Duplicate: true
```

The pairs checked are (“Rain”, “Echo”), (“Echo”, “Rain”) and (“Rain”, “Glow”). The first and the last pair are out of alphabetical order. Watch out: with `i < playlist.size()` the last pass calls `get(4)` and the program stops with an `IndexOutOfBoundsException`.

## 4\. Shift, rotate and reverse

A **shift** moves every element one place left or right. A **rotate** is a shift where the element that falls off one end comes back at the other end 4.10.A.1. With an ArrayList you can rotate by moving one element: `remove(0)` returns the first element, and `add` puts it at the end. You can also do it the array way, with `set` and a saved value.

To **reverse**, swap the first and last elements, then the second and second to last, and stop at the middle 4.10.A.1.

```
ArrayList<Integer> lane = new ArrayList<Integer>();
for (int k = 1; k <= 5; k++)
{
    lane.add(k * 10);
}

// rotate left by one, using set and a saved value
int first = lane.get(0);
for (int i = 0; i < lane.size() - 1; i++)
{
    lane.set(i, lane.get(i + 1));
}
lane.set(lane.size() - 1, first);
System.out.println(lane);

// rotate right by one, using remove and add
lane.add(0, lane.remove(lane.size() - 1));
System.out.println(lane);

// reverse: swap pairs from the outside in
for (int i = 0; i < lane.size() / 2; i++)
{
    int j = lane.size() - 1 - i;
    int temp = lane.get(i);
    lane.set(i, lane.get(j));
    lane.set(j, temp);
}
System.out.println(lane);
```

Output:

```
[20, 30, 40, 50, 10]
[10, 20, 30, 40, 50]
[50, 40, 30, 20, 10]
```

Watch out: if the reverse loop ran to `i < lane.size()`, it would swap every pair twice and the list would end up back in its original order.

## 5\. Inserting and deleting elements

`add(index, obj)` inserts and moves later elements right; `remove(index)` deletes and moves later elements left 4.10.A.1. Both change `size()`, so a loop that inserts or deletes must control its index carefully.

**Deleting.** The safest pattern runs backward. The elements that shift are the ones already visited, so nothing is skipped.

```
ArrayList<Integer> stock = new ArrayList<Integer>();
stock.add(0);
stock.add(0);
stock.add(7);
stock.add(0);
stock.add(3);

// buggy: forward loop always does i++
ArrayList<Integer> copy = new ArrayList<Integer>(stock);
for (int i = 0; i < copy.size(); i++)
{
    if (copy.get(i) == 0)
    {
        copy.remove(i);
    }
}
System.out.println("forward: " + copy);

// correct: backward loop
for (int i = stock.size() - 1; i >= 0; i--)
{
    if (stock.get(i) == 0)
    {
        stock.remove(i);
    }
}
System.out.println("backward: " + stock);
```

Output:

```
forward: [0, 7, 3]
backward: [7, 3]
```

Trace of the buggy loop: at `i = 0` the first 0 is removed and the second 0 slides into index 0, but `i` becomes 1, so that 0 is never checked.

**Inserting.** After inserting at index `i`, the element you were looking at is now at `i + 1`. Skip past the new element so the loop does not process it again (or insert forever).

```
ArrayList<String> line = new ArrayList<String>();
line.add("Ana");
line.add("VIP");
line.add("Ben");
line.add("VIP");

for (int i = 0; i < line.size(); i++)
{
    if (line.get(i).equals("VIP"))
    {
        line.add(i, "Guard");
        i++; // jump over the element we just inserted
    }
}
System.out.println(line);
```

Output:

```
[Ana, Guard, VIP, Ben, Guard, VIP]
```

Watch out: calling `add` or `remove` on a list inside an enhanced for loop over that same list throws a `ConcurrentModificationException`.

## 6\. Traversing more than one collection at a time

Some algorithms need two String, array or ArrayList objects at once 4.10.A.2. Two common shapes:

-   **Parallel traversal:** one index walks through both collections, so element `i` of one belongs with element `i` of the other.
-   **Nested traversal:** for each element of the first collection, walk through the whole second collection.

```
String[] players = {"Kai", "Lena", "Omar"};
ArrayList<Integer> goals = new ArrayList<Integer>();
goals.add(3);
goals.add(5);
goals.add(2);

String best = players[0];
int bestGoals = goals.get(0);
for (int i = 1; i < players.length; i++)
{
    if (goals.get(i) > bestGoals)
    {
        bestGoals = goals.get(i);
        best = players[i];
    }
}
System.out.println(best + " scored " + bestGoals);

// count letters of a word that also appear in a second word
String a = "plane";
String b = "apple";
int shared = 0;
for (int i = 0; i < a.length(); i++)
{
    if (b.indexOf(a.substring(i, i + 1)) >= 0)
    {
        shared++;
    }
}
System.out.println("shared letters: " + shared);
```

Output:

```
Lena scored 5
shared letters: 4
```

In “plane”, the letters p, l, a and e appear in “apple”; n does not. Watch out: parallel traversal only works if both collections have the same length, or if the loop stops at the shorter one.

## Common mix-ups

- Not true: You can remove elements in a forward for loop and simply move on with i++. After remove(i), every later element shifts one index left, so i++ skips the element that moved into position i. Loop backward, or only increase i when nothing was removed.
- Not true: Starting the maximum at 0 always works. If every value is negative, 0 is never replaced and the answer is wrong. Start with the first element (or Integer.MIN_VALUE).
- Not true: An "all elements" check can return true as soon as one element passes. One passing element proves nothing about the others. Return false at the first failure and return true only after the loop ends.
- Not true: size() and length work the same way on an ArrayList. An ArrayList uses the method call list.size() with parentheses. Arrays use the length attribute and strings use length().

## In 30 seconds

- Most ArrayList algorithms are one traversal plus a variable that remembers something (a best value, a total, a count or a flag).
- Seed min and max with the first element, compute averages with double division, and stop pair loops at size() - 1.
- "At least one" returns true early; "all" returns false early.
- add and remove change the size and shift later elements, so loops that insert or delete must adjust the index.
- Some algorithms traverse two collections together with one shared index, or with nested loops.

## Checkpoint: 5 practice questions

### Question 1

Consider the following code segment, which is intended to remove every even number from `nums`. What is printed as a result of executing the code segment?

```java
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(4);
nums.add(4);
nums.add(5);
nums.add(4);
nums.add(6);
for (int i = 0; i < nums.size(); i++)
{
    if (nums.get(i) % 2 == 0)
    {
        nums.remove(i);
    }
}
System.out.println(nums);
```

- A. [5]
- B. [4, 5, 6]
- C. [5, 6]
- D. [4, 5]

**Answer: B.** When `remove(i)` deletes an element, the next element slides into index `i`, but `i++` moves past it. At `i = 0` the first 4 is removed and the second 4 moves to index 0 unchecked; at `i = 2` the third 4 is removed and 6 moves to index 2 unchecked. The result is [4, 5, 6]. [5] is what a correct backward loop would print, and [5, 6] and [4, 5] each assume only one element was skipped.

### Question 2

The following method is intended to return `true` if every element of `nums` is positive and `false` otherwise. For which of the following lists does the method NOT return the intended value?

```java
public static boolean allPositive(ArrayList<Integer> nums)
{
    for (int n : nums)
    {
        if (n <= 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    return true;
}
```

- A. [3, 7, 9]
- B. [-2, 5, 8]
- C. [6, -1, 4]
- D. [0, 0, 0]

**Answer: C.** The `else` branch returns `true` after checking only the first element, so the method decides based on `nums.get(0)` alone. For [6, -1, 4] the first element is positive, so it returns `true` even though -1 is not positive. For [3, 7, 9] `true` is correct, and for [-2, 5, 8] and [0, 0, 0] the first element fails, so `false` is correct.

### Question 3

Consider the following code segment. What is printed as a result of executing the code segment?

```java
ArrayList<String> letters = new ArrayList<String>();
letters.add("a");
letters.add("b");
letters.add("c");
letters.add("d");
for (int k = 0; k < 2; k++)
{
    String last = letters.remove(letters.size() - 1);
    letters.add(0, last);
}
System.out.println(letters);
```

- A. [c, d, a, b]
- B. [b, c, d, a]
- C. [d, a, b, c]
- D. [a, b, c, d]

**Answer: A.** Each pass removes the last element and inserts it at index 0, which rotates the list right by one. After the first pass the list is [d, a, b, c]; after the second it is [c, d, a, b]. [d, a, b, c] stops after one pass, [b, c, d, a] is a rotation to the left, and [a, b, c, d] would need four passes.

### Question 4

Consider the following code segment. What is printed as a result of executing the code segment?

```java
ArrayList<Integer> rolls = new ArrayList<Integer>();
rolls.add(2);
rolls.add(2);
rolls.add(3);
rolls.add(3);
rolls.add(3);
rolls.add(1);
int same = 0;
for (int i = 0; i < rolls.size() - 1; i++)
{
    int a = rolls.get(i);
    int b = rolls.get(i + 1);
    if (a == b)
    {
        same++;
    }
}
System.out.println(same);
```

- A. 2
- B. 4
- C. 5
- D. 3

**Answer: D.** The loop visits the consecutive pairs (2, 2), (2, 3), (3, 3), (3, 3) and (3, 1). Three of them hold equal values. 2 counts runs of equal values instead of pairs, 5 counts every pair, and 4 would need one more equal pair.

### Question 5

A word game compares a secret `String` with a player's guess, stored one letter per element in an `ArrayList`. Consider the following code segment. What is printed as a result of executing the code segment?

```java
String secret = "CRANE";
ArrayList<String> guess = new ArrayList<String>();
guess.add("C");
guess.add("A");
guess.add("R");
guess.add("N");
guess.add("E");
int exact = 0;
for (int i = 0; i < secret.length(); i++)
{
    if (secret.substring(i, i + 1).equals(guess.get(i)))
    {
        exact++;
    }
}
System.out.println(exact);
```

- A. 2
- B. 3
- C. 5
- D. 4

**Answer: B.** The single index `i` traverses the `String` and the `ArrayList` at the same time. Positions 0 (C), 3 (N) and 4 (E) match; positions 1 and 2 hold the same letters in a different order, so they do not count. 5 counts letters that appear anywhere, and 2 and 4 miscount the matching positions.

## Questions students ask

**How do you remove elements from an ArrayList inside a loop in Java?**

Use an indexed for loop that runs backward from size() - 1 down to 0, or a forward loop that only increases the index when no element was removed. Never call remove inside an enhanced for loop over the same list.

**How do you find the maximum value in an ArrayList of Integer?**

Store list.get(0) in a variable, traverse the rest of the list, and replace the variable whenever an element is greater. Unboxing turns each Integer into an int for the comparison.

**How do you check an ArrayList for duplicates?**

Use nested loops: the outer loop picks an element and the inner loop compares it with every element after it. If any pair is equal, there is a duplicate.

**Which ArrayList algorithms are on the AP® Computer Science A exam?**

Minimum and maximum, sum and average, property checks (at least one, all, count), consecutive pairs, duplicates, shifting or rotating, reversing, inserting and deleting elements, plus algorithms that traverse more than one collection at once.

---

© LockInCS, licensed CC BY-NC-ND 4.0. AP® is a trademark registered by the College Board, which is not affiliated with, and does not endorse, this website.
