The 6 Traps
Trap #1
ConcurrentModificationException — The For-Each Killer
You cannot add or remove elements from an ArrayList while iterating with an enhanced for loop. Java throws ConcurrentModificationException at runtime.
ArrayListFIX: Standard for loop, iterate backwardsnames = new ArrayList (); names.add("Ana"); names.add("Ben"); names.add("Cal"); for (String n : names) { if (n.equals("Ben")) { names.remove(n); // ConcurrentModificationException } }
for (int i = names.size() - 1; i >= 0; i--)
{
if (names.get(i).equals("Ben"))
{
names.remove(i);
}
}
// names is now ["Ana", "Cal"]
Trap #2
Index Shifting After remove()
When you remove index i, every element after it shifts left. If you increment i normally, you skip the next element.
ArrayListFIX 1: Decrement after removalnums = new ArrayList (); // nums = [1, 2, 3, 4, 5] for (int i = 0; i < nums.size(); i++) { if (nums.get(i) % 2 == 0) { nums.remove(i); // After removing index 1 (value 2), // 3 shifts to index 1, but i becomes 2 // So 3 is never checked } }
for (int i = 0; i < nums.size(); i++)
{
if (nums.get(i) % 2 == 0)
{
nums.remove(i);
i--; // stay at same index
}
}
FIX 2: Backwards traversal (preferred)
for (int i = nums.size() - 1; i >= 0; i--)
{
if (nums.get(i) % 2 == 0)
{
nums.remove(i);
}
}
Trap #3
remove(int) vs remove(Object) — The Autoboxing Ambiguity
For ArrayList, calling remove(2) removes the element at index 2, not the Integer with value 2. This is because int matches the remove(int index) overload.
ArrayListTO REMOVE BY VALUEnums = new ArrayList (); nums.add(10); nums.add(20); nums.add(30); nums.remove(2); // Removes index 2 (value 30), NOT the value 2 // nums = [10, 20]
nums.remove(Integer.valueOf(20)); // Removes the first occurrence of value 20 // nums = [10, 30]
list.remove(1) on an ArrayList and asks what the list contains afterward. Students who think it removes the value 1 get it wrong.
Trap #4
Autoboxing null Into a Primitive
If an ArrayList contains null and you assign it to an int, Java tries to auto-unbox and throws NullPointerException.
ArrayListdata = new ArrayList (); data.add(5); data.add(null); data.add(10); int val = data.get(1); // NullPointerException // Cannot unbox null to int
ArrayList and sums values. If any element is null, the auto-unbox crashes. The exam asks “what happens when this code executes?”
Master ArrayList Before FRQ 3
The 4-Week Cram Kit includes day-by-day ArrayList drills designed to eliminate these traps.
Get the Cram Kit — $29.99 1-on-1 TutoringTrap #5
Forgetting That add(index, element) Shifts Elements Right
Calling add(i, element) inserts at position i and shifts everything at i and beyond one position to the right. The list grows by one. Students forget this when tracing code.
ArrayListitems = new ArrayList (); items.add("A"); items.add("B"); items.add("C"); items.add(1, "X"); // items = ["A", "X", "B", "C"] (not ["A", "X", "C"])
add and remove calls and asks for the final list. Track every shift on paper — skipping the shift is the most common trace error.
Trap #6
Adding Elements During Forward Traversal
If you add elements while traversing forward, size() grows and the loop may process newly added elements or run longer than expected.
ArrayListvals = new ArrayList (); vals.add(1); vals.add(2); vals.add(3); for (int i = 0; i < vals.size(); i++) { if (vals.get(i) == 2) { vals.add(i + 1, 99); // vals.size() just grew, loop runs longer // Risk of infinite loop if not careful } }
i by an extra 1 to skip the newly inserted element, or build a separate output list and add to that instead.
Stop Losing Points on ArrayList
54.5% of my AP CSA students score 5s. I can help you master these patterns.
4-Week Cram Kit — $29.99 Book Tutoring