Verified for the 2025 AP Computer Science A exam•Citation:
Just like with arrays, we often need to process each element in an ArrayList. Traversing an ArrayList
involves accessing each element one by one. In this guide, we'll explore different ways to traverse ArrayList
objects and some important considerations to keep in mind when doing so.
There are two main approaches for traversing an ArrayList
. When traversing, you'll often use the size() method to determine how many elements are in the list, and possibly the remove() method if you need to delete elements during traversal.
The traditional approach uses an indexed for loop or a while loop with a counter. This approach relies on the size()
method to determine the boundaries of our loop:
ArrayList<String> names = new ArrayList<String>(); names.add("Taylor"); names.add("Morgan"); names.add("Jordan"); // Traversing with a for loop for (int i = 0; i < names.size(); i++) { String name = names.get(i); System.out.println(name); } // Traversing with a while loop int i = 0; while (i < names.size()) { String name = names.get(i); System.out.println(name); i++; }
Key points about this approach:
set(int index, E obj)
The enhanced for loop (also called for-each loop) provides a cleaner syntax:
ArrayList<String> names = new ArrayList<String>(); names.add("Taylor"); names.add("Morgan"); names.add("Jordan"); // Traversing with enhanced for loop for (String name : names) { System.out.println(name); }
Key points about this approach:
ArrayIndexOutOfBoundsException
ArrayList
during traversalWhen working with ArrayList
indices, keep these important points in mind:
Valid indices start at 0 and end at size() - 1
Accessing an index value outside this range will result in an ArrayIndexOutOfBoundsException
This is the same behavior as regular arrays
ArrayList<Integer> numbers = new ArrayList<Integer>(); numbers.add(10); numbers.add(20); numbers.add(30); // Valid index access System.out.println(numbers.get(0)); // 10 System.out.println(numbers.get(2)); // 30 // Invalid index access - will throw ArrayIndexOutOfBoundsException // System.out.println(numbers.get(3)); // Error! // System.out.println(numbers.get(-1)); // Error!
Removing elements while traversing an ArrayList
requires special care. The remove()
method changes the size of the list and shifts elements, which can cause problems during traversal:
ArrayList<Integer> values = new ArrayList<Integer>(); values.add(5); values.add(10); values.add(15); values.add(20); values.add(25); // INCORRECT approach - can cause problems for (int i = 0; i < values.size(); i++) { if (values.get(i) > 15) { values.remove(i); // Problem: After removing, all elements shift left, // but the index i still increases, potentially skipping elements } } // BETTER approach - traverse backwards for (int i = values.size() - 1; i >= 0; i--) { if (values.get(i) > 15) { values.remove(i); } } // ANOTHER approach - use an iterator (more advanced) import java.util.Iterator; Iterator<Integer> iter = values.iterator(); while (iter.hasNext()) { if (iter.next() > 15) { iter.remove(); // Safe way to remove during iteration } }
You should not add or remove elements from an ArrayList
while traversing it with an enhanced for
loop. This can result in a ConcurrentModificationException error:
ArrayList<String> fruits = new ArrayList<String>(); fruits.add("Apple"); fruits.add("Banana"); fruits.add("Cherry"); // This will cause a ConcurrentModificationException try { for (String fruit : fruits) { if (fruit.equals("Banana")) { fruits.remove(fruit); // DON'T do this! } } } catch (Exception e) { System.out.println("Error: " + e); }
When using an enhanced for
loop to traverse an ArrayList
, you should not:
If you need to modify the ArrayList
while traversing it, use a standard indexed for
loop or an Iterator
.
ArrayList<Integer> numbers = new ArrayList<Integer>(); numbers.add(5); numbers.add(10); numbers.add(15); numbers.add(20); // Remove even numbers for (int i = numbers.size() - 1; i >= 0; i--) { if (numbers.get(i) % 2 == 0) { numbers.remove(i); } }
Traversing backwards is safer because when an element is removed, the indices of elements that have already been processed don't change.
ArrayList<String> names = new ArrayList<String>(); names.add("Alex"); names.add("Bailey"); names.add("Casey"); // Create a temporary list to store elements to remove ArrayList<String> toRemove = new ArrayList<String>(); // First pass: identify elements to remove for (String name : names) { if (name.startsWith("B")) { toRemove.add(name); } } // Second pass: remove the identified elements names.removeAll(toRemove);
ArrayList<Student> students = new ArrayList<Student>(); // Assume students is populated with Student objects // Find students with grade 'A' for (Student student : students) { if (student.getGrade().equals("A")) { System.out.println(student.getName() + " earned an A"); } }
ArrayList<Integer> scores = new ArrayList<Integer>(); // Assume scores is populated with test scores int countPassing = 0; for (int score : scores) { if (score >= 70) { countPassing++; } } System.out.println("Number of passing scores: " + countPassing);
ArrayList<Double> values = new ArrayList<Double>(); // Assume values is populated with numbers double sum = 0; double max = Double.MIN_VALUE; double min = Double.MAX_VALUE; for (double value : values) { sum += value; if (value > max) max = value; if (value < min) min = value; } double average = sum / values.size(); System.out.println("Average: " + average); System.out.println("Maximum: " + max); System.out.println("Minimum: " + min);
Traversing ArrayList
objects can be done with traditional for/while loops or with the enhanced for loop. Each approach has its strengths: indexed loops provide access to positions and allow safe modification, while enhanced for loops offer cleaner syntax. Remember that indices work the same way as in arrays (0 to size()-1), and be careful about modifying an ArrayList
during traversal to avoid exceptions. When you need to remove elements, consider using a backward traversal or a temporary collection to ensure safe and correct operation.