Looping Through Java Arrays
Iterate over Java arrays using classic for loops, enhanced for-each loops, and streams.
Reading array[0], array[1], array[2] by hand stops scaling around length 3. Java gives you several ways to visit every element of an array — pick the one that matches what you actually need to do.
The classic for loop
The index-based for is the most flexible form, and it's the only one that gives you the position you're at:
int[] scores = {90, 85, 73, 100, 62};
for (int i = 0; i < scores.length; i++) {
System.out.println(i + ": " + scores[i]);
}Use this when you need:
- the index (to print it, to compare neighbors, to skip ahead)
- to walk the array in reverse —
for (int i = scores.length - 1; i >= 0; i--) - to step by more than one —
i += 2 - to mutate the array — assigning to
scores[i]
The bound is always i < array.length, never a hard-coded number. If the array shrinks or grows later (or gets passed in), the loop still works.
The enhanced for — "for-each"
When all you need is the value of each element in order, the enhanced for is shorter and clearer:
int[] scores = {90, 85, 73, 100, 62};
int sum = 0;
for (int score : scores) {
sum += score;
}
System.out.println("sum = " + sum);Read the colon as "in": "for each int score in scores." The loop variable is a fresh copy of each element. You can't get the index this way, and you can't modify the array through score — assigning to score just rebinds the local variable.
Use the enhanced for for "do something with each value." Use the classic for whenever the index matters.
Reading vs. writing inside a loop
Inside a classic for, array[i] = newValue mutates the array in place:
int[] scores = {90, 85, 73, 100, 62};
for (int i = 0; i < scores.length; i++) {
scores[i] = scores[i] + 5; // give everyone a 5-point bonus
}The enhanced for cannot do this for primitives — score = score + 5 only changes the local copy:
for (int score : scores) {
score = score + 5; // no effect on scores
}For arrays of objects, the loop variable still references the same object as the array slot, so calling mutating methods on it does change what the array sees. But re-assigning the variable doesn't.
Streams over arrays
For numeric arrays, the Arrays.stream(...) helper gives you a pipeline-style API:
import java.util.Arrays;
int[] scores = {90, 85, 73, 100, 62};
int total = Arrays.stream(scores).sum();
double avg = Arrays.stream(scores).average().orElse(0);
int max = Arrays.stream(scores).max().orElse(0);For object arrays, Arrays.stream(...) returns a Stream<T> with the usual filter/map/reduce methods:
String[] names = {"Ada", "Linus", "Grace"};
long shortOnes = Arrays.stream(names).filter(n -> n.length() <= 3).count();Streams are expressive but they're not free — for tight inner loops, a plain for is faster and easier to debug. Reach for streams when the intent (sum, filter-then-count, group, transform) is what you want to make obvious.
forEach from the array side
There's no array.forEach(...). The closest equivalents are Arrays.stream(arr).forEach(...) (numeric or object) or, for object arrays, the Arrays.asList(arr).forEach(...) shortcut. Most of the time the plain for or enhanced for is fine — don't reach for forEach just to chase a different syntax.
Picking a loop
| You need | Use |
|---|---|
| Index (or step, or reverse) | classic for |
| Just the values, in order | enhanced for |
sum/avg/min/max/filter on numbers | Arrays.stream(...) |
| Transform an array into a new one | classic for or a stream + toArray |
| Mutate the array in place | classic for |
A worked example
What's next
You can now create arrays and walk them in every direction. Real-world data is often two-dimensional — a grid, a table, a board — and Java supports that with multidimensional arrays, which are really arrays of arrays.
Practice
Which loop should you use if you need each element's index?