Leepoint Java Reference Notes on the Java language and its standard library.

Reversing an array

Two indices walking toward each other. The whole exercise is where they stop.

public static void reverse(int[] a) {
    for (int i = 0, j = a.length - 1; i < j; i++, j--) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
}

One index starts at the front, one at the back, and they swap and step inward.

The condition

i < j, not i <= j and not i < a.length.

With i <= j and an odd length the middle element is swapped with itself — harmless but pointless. With i < a.length every element is swapped twice and the array comes back unchanged, which is the classic wrong answer to this exercise and looks correct until you test it.

Stopping at i < j also means no special case for odd lengths: the middle element is already where it belongs.

In place, or a copy

The version above modifies the caller’s array — there is nothing to return. If the original must survive:

public static int[] reversed(int[] a) {
    int[] out = new int[a.length];
    for (int i = 0; i < a.length; i++) {
        out[i] = a[a.length - 1 - i];
    }
    return out;
}

a.length - 1 - i is the mirror index. Off by one here is the other standard mistake — a.length - i overruns on the first iteration.

For objects

The same code works with an object array; only the type of tmp changes. A generic version:

public static <T> void reverse(T[] a) { ... }

Why not Collections.reverse

Collections.reverse takes a List, and an array is not one. This nearly works:

Collections.reverse(Arrays.asList(strings));   // works for object arrays

Arrays.asList wraps the array, and writes through to it, so the array really is reversed.

It does not work for primitives. Arrays.asList(intArray) produces a List<int[]> with a single element — the array itself — rather than a list of integers. It compiles and does nothing, which is worse than failing.

For a primitive array, write the loop or use a stream:

int[] out = IntStream.range(0, a.length)
                     .map(i -> a[a.length - 1 - i])
                     .toArray();

The loop is clearer and faster. This is one of the places where the stream version is not an improvement.