LeepointJava Reference

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.