Array Traversals
Why this matters
Imagine you’re building a feature for a shopping app. A user, let's call her Maya, has added five items to her cart. To show her the total price, your program needs to look at the price of the first item, add it to a running total, then look at the second item's price, add it, and so on, until it has "visited" every single item in her cart. You can't miss any, and you shouldn't count any twice.
This process of systematically visiting each element in a collection is called traversal. It’s one of the most fundamental and common tasks in programming. Today, we'll master the two main ways to traverse arrays in Java: the classic indexed for loop and the convenient enhanced for loop.
Concept overview
flowchart TD
A[Start: I need to traverse an array] --> B{Do I need the element's index?};
B -- Yes --> C[Use an indexed for loop<br>for (int i=0; i < arr.length; i++)];
B -- No --> D{Do I need to change the values<br>in a primitive array?};
D -- Yes --> C;
D -- No --> E[Use an enhanced for loop<br>for (Type var : arr)];
C --> F[You can access arr[i] and i];
E --> G[You can access each element directly];
G --> H{Can I modify objects this way?};
H -- Yes --> I[s.setGPA() works!];
H -- No --> J[This is a common misconception];
F --> K[End];
I --> K;
Core explanation
Once you have data stored in an array, the next logical step is to do something with that data. You might want to find the highest score, calculate the average, or search for a specific name. All these tasks require you to look through the array's elements one by one. This is traversal.
Think of an array as a row of numbered lockers in a school hallway. Traversing that array is like walking down the hall and opening each locker in order to inspect its contents.
The Classic Tool: The Indexed for Loop
The most common and flexible way to traverse an array is with a standard for loop that uses an index variable. This is like having a list of locker numbers (0, 1, 2, 3...) and visiting each one explicitly.
Let's say we have an array of test scores:
int[] scores = {88, 95, 72, 100, 91};
To print each score, we can use an indexed for loop:
// Standard indexed for loop
for (int i = 0; i < scores.length; i++) {
System.out.println("Score at index " + i + ": " + scores[i]);
}
Output:
Score at index 0: 88
Score at index 1: 95
Score at index 2: 72
Score at index 3: 100
Score at index 4: 91
Let's break that down:
int i = 0;: We declare an index variable,i, and start it at 0. This is crucial because array indices always start at 0.i < scores.length;: The loop continues as long asiis less than the length of the array. For our 5-element array,scores.lengthis 5. The loop will run forivalues 0, 1, 2, 3, and 4. Whenibecomes 5, the condition5 < 5is false, and the loop stops. This prevents the infamousArrayIndexOutOfBoundsException.i++: After each iteration, we increment our index to move to the next element.scores[i]: Inside the loop, we use the indexito access the element at that specific position.
You can also use a while loop to do the same thing, but you have to manage the index variable yourself. Indexed for loops are generally preferred because they package the initialization, condition, and increment all in one line.
The Convenient Shortcut: The Enhanced for Loop
Sometimes, you don't care about the index. You just want to get each element, one after another. For these situations, Java gives us the enhanced for loop (also called a "for-each" loop).
It's like telling a friend, "For each locker in this hallway, just tell me what's inside." You don't care if it's locker #0 or locker #27; you just want the contents.
Here's the same task using an enhanced for loop:
// Enhanced for loop
for (int score : scores) {
System.out.println("A score is: " + score);
}
Output:
A score is: 88
A score is: 95
A score is: 72
A score is: 100
A score is: 91
The syntax for (int score : scores) reads as "for each int score in the scores array...".
- On the first pass, the variable
scoreis automatically assigned a copy ofscores[0](which is 88). - On the second pass,
scoreis assigned a copy ofscores[1](which is 95). - ...and so on, until every element has been visited.
A Critical Distinction: Modifying Elements
This is where many students get stuck. The behavior of assignment within a loop depends on whether you're using an indexed loop or an enhanced loop, and whether your array holds primitives (int, double) or objects (String, or custom objects like Student).
1. Primitives and the Enhanced for Loop
When you use an enhanced for loop with primitives, the loop variable gets a copy of the value. Changing that copy does not change the original array.
Imagine you have a photocopy of a page from a book. If you write on the photocopy, does the original book change? No.
int[] numbers = {10, 20, 30};
// Let's try to double every number
for (int num : numbers) {
num = num * 2; // This only changes the copy, 'num'
}
// Now let's print the array to see what happened
// The original array is UNCHANGED.
System.out.println(numbers[0]); // Prints 10, not 20
Assigning a new value to num has no effect on the numbers array itself. If you need to modify the elements of a primitive array, you must use an indexed for loop.
// The correct way to modify the array
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] * 2; // This directly accesses and changes the array
}
System.out.println(numbers[0]); // Prints 20
2. Objects and the Enhanced for Loop
This gets a little more nuanced. When an array stores objects, the array actually holds references—think of them as addresses pointing to where the objects live in memory.
When you use an enhanced for loop with an array of objects, the loop variable gets a copy of the reference.
Here's the analogy: Instead of a photocopy of a page, you get a photocopy of a key to a house. You can't use your copy of the key to change which house it opens (you can't change the reference), but you can use it to unlock the door and go inside to redecorate (you can change the object's state).
Let's say we have a simple Student class:
class Student {
private String name;
private double gpa;
// constructor, getters, setters...
public void setGpa(double newGpa) {
this.gpa = newGpa;
}
}
Student[] myStudents = { new Student("Priya", 3.8), new Student("Carlos", 3.5) };
// Let's give everyone a GPA boost
for (Student s : myStudents) {
s.setGpa(s.getGpa() + 0.1); // This WORKS!
}
In this case, s is a copy of the reference to a Student object. The line s.setGpa(...) uses that reference to find the original Student object in memory and call a method on it. The object itself is modified. The array still holds the same references to the same objects, but the objects themselves have changed.
Any traversal written with an enhanced for loop can be rewritten with an indexed for loop. The reverse is not always true, especially if you need the index for your logic.
See it in action
Worked examples
Let's walk through a few common scenarios to make this concrete.
Calculating the Total Cost
Problem: You have an array of doubles representing the prices of items in a shopping cart. Calculate the total cost, then add a 6% sales tax (like in Dallas, TX).
double[] prices = {19.99, 45.50, 5.25, 89.99};
Solution Walkthrough:
- 1GoalWe need to sum up all the values in the
pricesarray. This is a classic traversal task. - 2Loop ChoiceWe just need to read each value. We don't need the index. An enhanced
forloop is a perfect, clean choice. - 3Initialize a TotalBefore the loop starts, we need a variable to keep track of our running total. Let's call it
subtotaland initialize it to 0.0. - 4Write the LoopWe'll loop through each
pricein thepricesarray and add it to oursubtotal. - 5Calculate Final PriceAfter the loop finishes,
subtotalwill hold the sum of all prices. We then calculate the tax and add it to get the final total.
Code:
double[] prices = {19.99, 45.50, 5.25, 89.99};
double subtotal = 0.0;
// Use an enhanced for loop to sum the prices
<figure class="lesson-figure"><div class="shr-widget" data-shr-widget="{"code":["double[] prices = {19.99, 45.50, 5.25, 89.99};","double subtotal = 0.0;","for (double price : prices) {"," subtotal += price;","}"],"type":"for_loop_trace","array":[19.99,45.5,5.25,89.99],"trace_steps":[{"line":2,"vars":{"subtotal":0}},{"line":3,"vars":{"price":19.99,"subtotal":0},"highlight_cell":0},{"line":4,"vars":{"price":19.99,"subtotal":19.99},"highlight_cell":0},{"line":3,"vars":{"price":45.5,"subtotal":19.99},"highlight_cell":1},{"line":4,"vars":{"price":45.5,"subtotal":65.49},"highlight_cell":1},{"line":3,"vars":{"price":5.25,"subtotal":65.49},"highlight_cell":2},{"line":4,"vars":{"price":5.25,"subtotal":70.74},"highlight_cell":2},{"line":3,"vars":{"price":89.99,"subtotal":70.74},"highlight_cell":3},{"line":4,"vars":{"price":89.99,"subtotal":160.73},"highlight_cell":3}]}" aria-label="An animation showing an enhanced for loop. The 'price' variable takes on each value from the 'prices' array sequentially, and 'subtotal' accumulates the sum."></div><figcaption class="lesson-figure-caption">Tracing an enhanced `for` loop to calculate the subtotal of prices.</figcaption></figure>
for (double price : prices) {
subtotal += price; // same as subtotal = subtotal + price;
}
// Now calculate the final total with a 6% tax
double taxRate = 0.06;
double taxAmount = subtotal * taxRate;
double finalTotal = subtotal + taxAmount;
// Let's print it out, formatted nicely
System.out.printf("Subtotal: $%.2f\n", subtotal);
System.out.printf("Total with tax: $%.2f\n", finalTotal);
Finding the First Negative Temperature
Problem: You have an array of daily high temperatures for a week in Boston in January. Find the index of the first day the temperature dropped below freezing (0°F). If all temperatures are at or above freezing, return -1.
int[] temps = {12, 8, 2, -5, 3, -1, 6};
Solution Walkthrough:
- 1GoalWe need to find the index of a specific value.
- 2Loop ChoiceBecause the problem explicitly asks for the index, we must use an indexed
forloop. An enhancedforloop won't work here because it doesn't give us the index. - 3Write the LoopWe'll iterate from
i = 0up to the end of the array. - 4Check the ConditionInside the loop, we'll check if
temps[i] < 0. - 5Exit EarlyAs soon as we find the first negative temperature, we've accomplished our goal. We can print the index and stop searching. A
returnstatement or abreakis perfect for this. If we finish the entire loop without finding a negative number, we know none exist.
Code:
int[] temps = {12, 8, 2, -5, 3, -1, 6};
int firstFreezingIndex = -1; // Default value if none are found
for (int i = 0; i < temps.length; i++) {
if (temps[i] < 0) {
firstFreezingIndex = i;
break; // We found it! Exit the loop immediately.
}
}
System.out.println("The first day below freezing was at index: " + firstFreezingIndex);
// Output: The first day below freezing was at index: 3
Try it yourself
Time to put your knowledge into practice. Don't just read—code!
Problem 1: Find the Max
Write a method findMax that takes an array of integers and returns the largest value in the array. For example, if the input is {1, 9, 2, 8, 5}, your method should return 9.
- HintYou'll need a variable to keep track of the "biggest value seen so far." Initialize it to the first element of the array before the loop starts. Then, loop through the rest of the elements, updating your variable whenever you find a bigger one.
- HintCan you use an enhanced
forloop for this? Yes, because you don't need the index.
Problem 2: Count Occurrences
Write a method countLetterA that takes an array of Strings and returns how many of the strings start with the letter "A" (case-insensitive). For example, if the input is {"Apple", "Banana", "apricot", "Cherry"}, your method should return 2.
- HintYou'll need a counter variable, initialized to 0 before the loop.
- HintThe
Stringclass has helpful methods likestartsWith()andtoUpperCase()ortoLowerCase()to handle the case-insensitivity.
Practice — 8 questions
In simple terms, array traversal is about visiting each item in an array, one by one, to read, count, or check its value, much like checking off items on a list.
int[] scores = {88, 95, 72, 100, 91};
- 4.4.A: Develop code used to traverse the elements in a 1D array and determine the result of these traversals.
- 4.4.A.1
- Traversing an array is when repetition statements are used to access all or an ordered sequence of elements in an array.
- 4.4.A.2
- Traversing an array with an indexed for loop or while loop requires elements to be accessed using their indices.
- 4.4.A.3
- An enhanced for loop header includes a variable, referred to as the enhanced for loop variable. For each iteration of the enhanced for loop, the enhanced for loop variable is assigned a copy of an element without using its index.
- 4.4.A.4
- Assigning a new value to the enhanced for loop variable does not change the value stored in the array.
- 4.4.A.5
- When an array stores object references, the attributes can be modified by calling methods on the enhanced for loop variable. This does not change the object references stored in the array.
- 4.4.A.6
- Code written using an enhanced for loop to traverse elements in an array can be rewritten using an indexed for loop or a while loop.
flowchart TD
A[Start: I need to traverse an array] --> B{Do I need the element's index?};
B -- Yes --> C[Use an indexed for loop<br>for (int i=0; i < arr.length; i++)];
B -- No --> D{Do I need to change the values<br>in a primitive array?};
D -- Yes --> C;
D -- No --> E[Use an enhanced for loop<br>for (Type var : arr)];
C --> F[You can access arr[i] and i];
E --> G[You can access each element directly];
G --> H{Can I modify objects this way?};
H -- Yes --> I[s.setGPA() works!];
H -- No --> J[This is a common misconception];
F --> K[End];
I --> K;
Read what Saavi narrates
Hi everyone, it's Saavi from Shrutam. Let's talk about one of the most common things you'll ever do in programming.
Imagine you're building a shopping app. A user, Maya, adds five items to her cart. To show her the total price, your code has to look at the first item's price, add it up, then the second, then the third, and so on, until it's visited every single item. This process of systematically visiting each element is called traversal. It's like walking down a list and checking off every item.
In Java, we have two main ways to do this with arrays. The first is the classic indexed for loop, where you use a counter to visit by position: index 0, index 1, index 2... The second is the enhanced for loop, which is simpler. It just says, "give me each item, one by one."
Let's look at a quick example. Say we have an array of prices for items in a cart. We want to find the total.
First, we'd create a variable for the subtotal, and set it to zero. Then, we can use an enhanced for loop. For each price in our prices array, we just add that price to our subtotal. The loop handles grabbing each value for us automatically. After the loop is done, we have our sum. Simple as that.
Now, here's a really common mistake students make. Let's say you have an array of numbers, and you want to double every number in it. You might try an enhanced for loop, like this: for each number in the array, set the number equal to itself times two.
But... it won't work. When you use an enhanced for loop on simple types like numbers, the loop variable is just a *copy*. It's like writing on a photocopy... the original document doesn't change. To actually modify the array, you *must* use the classic indexed for loop, which lets you directly access and change the value at each position.
It's a small detail, but it's critical for the AP exam.
So, remember: traversal is just visiting every element. Use an enhanced for loop when you just need to read values. Use an indexed for loop when you need the element's position or when you need to change the values in the array.
You've got this. Keep practicing, and I'll see you in the next lesson.
Writing `for (int i = 0; i <= scores.length; i++)`. The last valid index is `scores.length - 1`. When `i` equals `scores.length`, `scores[i]` will throw an `ArrayIndexOutOfBoundsException`.
Always use `<` not `<=` in a standard forward-iterating loop: `for (int i = 0; i < scores.length; i++)`.
`for (int val : myArray) { val = 0; }` does not change `myArray`. The loop variable `val` is a *copy*. Modifying the copy doesn't affect the original.
If you need to change the array's contents, use an indexed loop: `for (int i = 0; i < myArray.length; i++) { myArray[i] = 0; }`.
The enhanced `for` loop is specifically designed to hide the index from you for simplicity. There is no built-in way to get the index `i` inside `for (String name : names) { ... }`.
If you need the index for any reason (e.g., "print the name at position 5"), you must use an indexed `for` loop.
If you're calculating a sum, `for (...) { int total = 0; total += value; }` will reset `total` to zero on every single iteration, and your final result will just be the last element's value.
Always initialize accumulator variables (like a sum or a count) *before* the loop begins.
`for (int i = 1; i < data.length; i++)` will completely skip the first element of the array at index 0.
Unless you have a very specific reason, always start your index at 0 to process the entire array.
Students learn you can't modify arrays with enhanced loops, but forget the object exception. `for (Student s : students) { s.setGPA(4.0); }` *does* work because you are modifying the state of the object that the array *refers* to.
Remember the "copy of a key" analogy. You can use the key to change things inside the house.