Full explanation and traced examples: Topic 4.9 study guide.
Recap
Traversing an ArrayList means visiting its elements in order. The standard indexed loop runs i from 0 to size() - 1. The enhanced for loop reads each element without an index. A while loop lets you hold the index still. Reading and replacing (get, set) are safe during a traversal; adding and removing change the size and need care.
for (int i = 0; i < list.size(); i++) // indexed
{
int x = list.get(i);
}
for (int x : list) // enhanced
{
System.out.println(x);
}
for (int i = list.size() - 1; i >= 0; i--) // backward: safe for remove
{
if (list.get(i) < 0) { list.remove(i); }
}
Key relationships
| Situation | Safe approach | Why |
|---|---|---|
| Read every element | enhanced for or indexed for |
no size change |
| Replace elements | indexed for with set(i, x) |
set does not shift anything |
| Remove matches | backward for, or while that skips i++ after a removal |
later elements move left |
Remove inside enhanced for |
avoid | may throw ConcurrentModificationException |
| Index loop condition | i < list.size() |
i <= list.size() throws IndexOutOfBoundsException |
Assumptions
- The list is not
nulland holds the element type you expect. - No other code changes the list while the loop runs.
- Elements are compared with
equalswhen they are Strings or other objects.
A mini-example to rehearse
Remove the negatives from [3, -1, -2, 5, -4]. A forward loop with remove(i) gives [3, -2, 5]: after -1 is removed, -2 slides into index 1 and the loop’s i++ jumps over it. The backward loop gives [3, 5]. A while loop that adds one to i only in the else-branch also gives [3, 5]. On [1, -2, 3, -4, 5, -6] the forward bug happens to give the right answer, because no two negatives are adjacent, so test with adjacent matches.
Mistakes to avoid
- Writing
<=in the loop condition. - Removing in a forward loop without compensating.
- Removing or adding inside an enhanced
forloop. - Assigning to the enhanced
forvariable and expecting the list to change. - Calling
get(i)after a removal without rechecking thatiis still valid. - Using
==to compare Strings in a condition; useequals.
How this topic is usually tested
- Trace a loop that removes elements and give the final list.
- Identify the bug in a deletion loop and say which element is skipped.
- Predict an exception:
IndexOutOfBoundsExceptionorConcurrentModificationException. - Write a method that removes all elements matching a condition.
Quick self-check
- Forward loop removes every
"b"from[a, b, b, c]. Result?[a, b, c], since the secondbis skipped. - Same task with a backward loop?
[a, c]. - What does
for (Integer x : d) { x = x * 2; }do tod? Nothing. - Which loop condition throws on the last pass:
i < size()ori <= size()?i <= size(). - Which exception can removing inside an enhanced for loop cause?
ConcurrentModificationException.