How a reverse for loop works
A Java for loop has three parts in its header: a starting statement, a condition that decides whether to keep going, and an update that runs after every pass. A normal loop counts up, with i++ as the update. To loop in reverse, change all three parts so that they work together in the other direction:
- Start at the highest value.
- Keep going while the variable is still greater than (or equal to) the lowest value you want.
- Update with
i--so the variable shrinks by one each pass.
for (int i = 7; i > 2; i--) {
System.out.println(i);
}
This prints 7, 6, 5, 4 and 3, each on its own line. The loop stops once i becomes 2, because 2 > 2 is false. Writing i >= 3 instead gives exactly the same output. The comparison operator is what decides whether the last value is included, so pick it deliberately.
The exercise: print 5 down to -5
The lesson asks for every whole number from 5 through -5, in decreasing order, one per line. That is 11 numbers, because zero and both ends count.
- Write the loop header. Start with
int i = 5. Usei >= -5as the condition, noti > -5, because -5 itself must be printed. The update isi--. - Print inside the body.
System.out.println(i)prints the current value and moves to a new line.
for (int i = 5; i >= -5; i--) {
System.out.println(i);
}
The output is:
5
4
3
2
1
0
-1
-2
-3
-4
-5
Nothing special happens when i crosses zero. It is an ordinary int, and negative values work like any others.
Counting down by more than one
The update does not have to be i--. Any expression that moves the variable downward works. With i -= 3 the loop skips values:
for (int i = 10; i > 0; i -= 3) {
System.out.print(i + " ");
}
This prints 10 7 4 1. The next value would be -2, and -2 > 0 is false, so the loop ends.
Looping over an array or a string backwards
The most common reason to loop in reverse is to visit the elements of an array, a list or a string from the last to the first. Valid indexes run from 0 to length - 1, so the loop starts at length - 1 and stops after index 0:
int[] a = {10, 20, 30, 40};
for (int i = a.length - 1; i >= 0; i--) {
System.out.print(a[i] + " ");
}
This prints 40 30 20 10. The same pattern with s.length() - 1 and s.charAt(i) walks a string backwards, which is the usual way to reverse a string by hand: append each character to a StringBuilder as the loop goes, and "hello" becomes "olleh". The same pattern works on lists with size() and get(i).
Going backwards is also the safe way to remove items from an ArrayList while looping. Removing an element shifts everything after it one place to the left. If you loop from the end, the elements you have not visited yet are the ones before the removal, so none are skipped:
List<Integer> nums = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6));
for (int i = nums.size() - 1; i >= 0; i--) {
if (nums.get(i) % 2 == 0) {
nums.remove(i);
}
}
After the loop, nums is [1, 3, 5].
Other ways to go through a collection in reverse
- The enhanced for loop (for-each) cannot go backwards. It always visits elements first to last and gives no index. To use it in reverse, reverse a copy of the data first, for example with
Collections.reverse(list), but that changes the list. For simple cases, the index loop above is clearer. - A list iterator.
list.listIterator(list.size())starts at the end, and awhile (it.hasPrevious())loop callingit.previous()visits the elements backwards without indexes. - A deque.
ArrayDequeandLinkedListofferdescendingIterator(), which walks from the last element to the first.
Common mistakes
- Using
i++by habit.for (int i = 5; i >= -5; i++)moves away from the stopping point. The condition stays true whileiclimbs through about two billion values, until theintoverflows past its maximum and wraps to a large negative number. Only then does the loop end, after a very long run that prints far more than intended. Always check that the update moves toward the stopping point. - Using
>when you need>=.i > 0stops before printing 0. When looping over array indexes,i > 0skips index 0, the first element. This is the most common off-by-one error in reverse loops. - Starting at
lengthinstead oflength - 1.a[a.length]is outside the array and throws anArrayIndexOutOfBoundsException. - A start value that already fails the condition.
for (int i = 5; i > 5; i--)never runs its body. The condition is checked before the first pass. - Counting up and down at once. Pick the direction in the header. Changing
iagain inside the body usually makes the loop hard to follow.
Key takeaways
- A reverse loop starts high, tests with
>or>=, and updates withi--ori -= step. - Choose
>=when the last value must be included:i >= -5prints -5, whilei > -5stops at -4. - To visit an array backwards, run from
length - 1down to0. - Looping from the end is the safe way to remove elements from a list as you go.
