ArrayList Traversals
Same Loop Shapes as Arrays
For-each, indexed for, and while all work on an ArrayList — just with get(i) instead of [i], and .size() instead of .length:
// for-each — read-only pass
for (String log : logs) { System.out.println(log); }
// indexed
for (int i = 0; i < logs.size(); i++) { System.out.println(logs.get(i)); }
The Big Restriction: Don't Resize During a For-Each
Adding or removing elements from an ArrayList while a for-each loop is traversing it usually throws ConcurrentModificationException — but not always. Remove the second-to-last element and the loop can end silently instead, quietly skipping the last element rather than throwing anything. Either way, it's broken; never rely on the exception to catch this for you. If you need to add or remove while looping, use an indexed for or while loop instead.
Removing While Looping — The Careful Way
Removing an element shifts every later element down by one index. If you increment the loop index unconditionally after a removal, you skip checking the element that just got shifted into the spot you were on:
int i = 0;
while (i < logs.size())
{
if (shouldRemove(logs.get(i)))
{
// don't increment i here — the next element just shifted into index i
logs.remove(i);
}
else
{
i++; // only advance when nothing was removed this iteration
}
}
Chaining Through a List of Objects
// assume RobotPart exists, with getName() — Ch.17 builds it out fully
ArrayList<RobotPart> parts = new ArrayList<RobotPart>();
// chain: get the object, then call a method on it
String firstName = parts.get(0).getName();
Removing Without the Careful Index Dance
Once interfaces and generics are covered (Ch.19), removeIf(condition) and the Iterator's own remove() do this same job in one call, without the manual index bookkeeping above — a preview worth knowing about, not required yet.
Common Pitfalls
- Adding/removing inside a for-each loop. Usually throws
ConcurrentModificationException, but can also silently skip an element instead — switch to an indexedfororwhileloop if the list's size needs to change mid-traversal. - Incrementing the index unconditionally after a
remove. This skips the element that shifted into the just-vacated slot — only advance the index when you didn't remove anything that pass. - Using
<=against.size(). Same off-by-one risk as arrays — the last valid index issize() - 1.
Key Takeaways
ArrayListsupports the same loop shapes as arrays, usingget(i)/.size()instead of[i]/.length.- Never add or remove elements from an
ArrayListwhile traversing it with a for-each loop — it usually throws, but can also fail silently instead. - When removing elements in an indexed/while loop, only advance the index on iterations where nothing was removed.
removeIf()/Iterator.remove()(Ch.19) do this more directly once interfaces are covered.
Derived from csawesome-2026: unit-4-data-collections/4.09-arraylist-traversals.md (CSA 4.9)