Lesson 4.9: Traversing ArrayLists

Unit 4 · Lesson 4.9 · ArrayList

Lesson 4.9: Traversing ArrayLists

🕑 40–50 min · 10 Practice Questions · For Loop · For-Each · Remove While Traversing

What You'll Learn

  • 4.9.A: Traverse the elements in an ArrayList.
  • Write standard for loops and for-each loops over ArrayLists.
  • Explain why removing elements during a standard for loop requires adjusting the index.
  • Identify the off-by-one and skipped-element bugs that occur when modifying a list during traversal.
  • Choose the correct loop type based on whether the list will be modified.

Key Vocabulary

Term Definition
ConcurrentModificationException A runtime exception thrown when a list is structurally modified (elements added or removed) while a for-each loop is iterating over it.
index adjustment Decrementing the loop counter after a removal so the next element (which shifted left) is not skipped.

Standard For Loop Traversal

The standard for loop traverses an ArrayList using size() as the bound and get(i) to access each element:

ArrayList names = new ArrayList();
names.add("Alice");
names.add("Ben");
names.add("Carlos");

for (int i = 0; i < names.size(); i++) {
    System.out.println(names.get(i));
}

⚠️ AP Exam Trap: size() not length

The loop bound must be names.size(), not names.length. length is the array field — it doesn't exist on ArrayList. Using it causes a compile error.

For-Each Loop Traversal

When you only need to read every element front to back, the for-each loop is cleaner:

for (String name : names) {
    System.out.println(name);
}

Read it as: "for each String named name in names, do..." — identical to how for-each works on arrays.

⚠️ AP Exam Trap: Never Remove Inside a For-Each

Removing an element from an ArrayList while a for-each loop is iterating over it throws a ConcurrentModificationException at runtime. If you need to remove elements during traversal, you must use a standard for loop with an index adjustment.

Removing Elements During Traversal

This is the most heavily tested ArrayList traversal concept on the AP exam. When you remove an element at index i, everything after it shifts left — the next element is now at index i, not i+1. If the loop then increments i normally, that next element gets skipped.

The fix: decrement i after every removal.

// Remove all elements less than 5
ArrayList nums = new ArrayList();
nums.add(3);
nums.add(8);
nums.add(2);
nums.add(9);
nums.add(1);

for (int i = 0; i < nums.size(); i++) {
    if (nums.get(i) < 5) {
        nums.remove(i);
        i--;  // ← adjust for the left shift
    }
}
// nums: [8, 9]

✅ Tracing the Index Adjustment

Without i--: start [3,8,2,9,1]. i=0: remove 3 → [8,2,9,1]. i increments to 1. But the element that shifted to index 0 (value 8) was already passed — it's fine here. Now at index 1 is 2. Remove 2 → [8,9,1]. i increments to 2. Index 2 is 1 — remove it → [8,9]. i=3, size=2, loop ends. Works here by accident.

The problem is when two consecutive qualifying elements appear: [3,2,9]. i=0: remove 3 → [2,9]. i increments to 1. Index 1 is 9 — skips 2 entirely! With i--: after removing 3, i goes back to 0, sees 2, removes it, result [9]. Correct.

Choosing the Right Loop

Situation Use This Loop
Read every element, no modification for-each ✓
Remove elements during traversal standard for + i-- ✓
Replace elements (set) during traversal standard for ✓
Need the index value itself standard for ✓
Traverse in reverse standard for (decrement) ✓

Summary

  • Standard for loop: for (int i = 0; i < list.size(); i++) with list.get(i).
  • For-each loop: for (Type x : list) — cleaner but cannot modify the list structure.
  • Removing during a for loop: always add i-- after the removal to avoid skipping the element that shifted into position.
  • Never remove inside a for-each loop — throws ConcurrentModificationException.

Practice Questions

MCQ 1
What is printed?
ArrayList list = new ArrayList();
list.add(10);
list.add(20);
list.add(30);
int sum = 0;
for (int x : list) {
    sum += x;
}
System.out.println(sum);
Predict before reading the options.
A 20
B 60
C 30
D 3
B. The for-each visits all three elements: 10+20+30 = 60.
MCQ 2
Which code correctly prints every element of an ArrayList named words?
A
for (int i = 0; i < words.length; i++) {
    System.out.println(words.get(i));
}
B
for (int i = 0; i <= words.size(); i++) {
    System.out.println(words.get(i));
}
C
for (int i = 0; i < words.size(); i++) {
    System.out.println(words.get(i));
}
D
for (int i = 1; i < words.size(); i++) {
    System.out.println(words.get(i));
}
C. A uses words.length — ArrayList has no length field, compile error. B uses <= — throws IndexOutOfBoundsException on the last iteration. D starts at 1 — skips index 0. C is the correct pattern.
MCQ 3
A student removes elements from an ArrayList inside a for-each loop. What happens at runtime?
A A ConcurrentModificationException is thrown.
B The element is removed and the loop continues normally.
C A compile error occurs.
D The loop silently skips the removed element.
A. Java detects that the list was structurally modified during iteration and throws ConcurrentModificationException at runtime. This is not a compile error — the code looks valid to the compiler.
MCQ 4
After this code runs, what does list contain?
ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for (int i = 0; i < list.size(); i++) {
    if (list.get(i) % 2 == 0) {
        list.remove(i);
        i--;
    }
}
Trace carefully — the i-- is there.
A [1, 3]
B [1, 3, 4, 5]
C [2, 4]
D [1, 3, 5]
D. The loop removes all even numbers. With i-- correctly adjusting after each removal, no elements are skipped. 2 and 4 are removed, leaving [1,3,5].
MCQ 5
What does this code produce?
ArrayList list = new ArrayList();
list.add(2);
list.add(4);
list.add(6);
for (int i = 0; i < list.size(); i++) {
    if (list.get(i) % 2 == 0) {
        list.remove(i);
    }
}
No i-- this time — trace what gets skipped.
A list is empty []
B [4]
C [2, 6]
D [6]
B. Without i--, elements shift left but the index still increments. i=0: remove 2 → [4,6]. i increments to 1. Index 1 is 6 — remove it → [4]. i increments to 2, size is 1, loop ends. 4 was skipped entirely because after removing 2, it shifted to index 0, but i jumped to 1.
Tier 3 · AP Mastery

Mastery: Traversing ArrayLists

MCQ 6
Which method correctly removes all strings of length greater than 3 from an ArrayList named words?
Predict before reading the options.
A
for (String w : words) {
    if (w.length() > 3) {
        words.remove(w);
    }
}
B
for (int i = 0; i < words.size(); i++) {
    if (words.get(i).length() > 3) {
        words.remove(i);
    }
}
C
for (int i = 0; i < words.size(); i++) {
    if (words.get(i).length() > 3) {
        words.remove(i);
        i--;
    }
}
D
for (int i = words.size(); i >= 0; i--) {
    if (words.get(i).length() > 3) {
        words.remove(i);
    }
}
C. A uses for-each with remove — throws ConcurrentModificationException. B removes without i-- — skips elements after each removal. D starts at words.size() which is out of bounds (valid indices are 0 to size-1). C is correct: removes and adjusts index each time.
MCQ 7
What is printed?
ArrayList list = new ArrayList();
list.add(5);
list.add(3);
list.add(8);
list.add(3);
list.add(7);
int count = 0;
for (int x : list) {
    if (x == 3) count++;
}
System.out.println(count);
Predict before reading the options.
A 2
B 1
C 3
D 5
A. The for-each counts how many elements equal 3. Values 5, 3, 8, 3, 7 — 3 appears twice. Count = 2. The list is not modified so for-each is the correct and safe choice here.
MCQ 8
A Student class has getGpa() returning a double. Which code correctly removes all students with GPA below 2.0 from roster?
Predict before reading the options.
A
for (Student s : roster) {
    if (s.getGpa() < 2.0) {
        roster.remove(s);
    }
}
B
for (int i = 1; i < roster.size(); i++) {
    if (roster.get(i).getGpa() < 2.0) {
        roster.remove(i);
        i--;
    }
}
C
for (int i = 0; i < roster.size(); i++) {
    if (roster.get(i).getGpa() < 2.0) {
        roster.remove(i);
    }
}
D
for (int i = 0; i < roster.size(); i++) {
    if (roster.get(i).getGpa() < 2.0) {
        roster.remove(i);
        i--;
    }
}
D. A uses for-each with remove — ConcurrentModificationException. B starts at index 1 — skips roster[0]. C removes without i-- — may skip consecutive qualifying students. D starts at 0, uses i-- after each removal — correct.
MCQ 9
What is printed?
ArrayList list = new ArrayList();
list.add(1);
list.add(1);
list.add(2);
list.add(1);
for (int i = 0; i < list.size(); i++) {
    if (list.get(i) == 1) {
        list.remove(i);
        i--;
    }
}
System.out.println(list.size());
Predict before reading the options.
A 0
B 1
C 2
D 3
B. All three 1s are removed (with i-- ensuring consecutive 1s aren't skipped). Only the 2 remains. Size = 1.
MCQ 10
Which loop is most appropriate when you need to replace every element in an ArrayList with double its value?
A
for (int x : list) {
    x = x * 2;
}
B
for (Integer x : list) {
    x = x * 2;
}
C
for (int i = 0; i < list.size(); i++) {
    list.set(i, list.get(i) * 2);
}
D
for (int i = 0; i < list.size(); i++) {
    list.add(i, list.get(i) * 2);
}
C. A and B both use for-each — assigning to the loop variable never modifies the list. D uses add which inserts new elements and grows the list infinitely. C uses set to replace each element in place — the correct approach.

Get in Touch

Whether you're a student, parent, or teacher — I'd love to hear from you.

Just want free AP CS resources?

Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.

Typically responds within 24 hours

Message Sent!

Thanks for reaching out. I'll get back to you within 24 hours.

🏫 Welcome, fellow educator!

I offer curriculum resources, practice materials, and study guides designed for AP CS teachers. Let me know what you're looking for — whether it's classroom materials, a guest speaker, or Teachers Pay Teachers resources.

Email

[email protected]

📚

Courses

AP CSA, CSP, & Cybersecurity

Response Time

Within 24 hours

Prefer email? Reach me directly at [email protected]