1.9. Cloning and Reversing Arrays

Problem

You need to reverse and clone the contents of an array.

Solution

Use ArrayUtils.clone() and ArrayUtils.reverse() methods from Commons Lang. Example 1-5 demonstrates the reversal and cloning of a primitive array full of long primitives.

Example 1-5. Cloning and reversing a primitive array with ArrayUtils

import org.apache.commons.lang.ArrayUtils;

long[] array = { 1, 3, 2, 3, 5, 6 };
long[] reversed = ArrayUtils.clone( array );
ArrayUtils.reverse( reversed );

System.out.println( "Original: " + ArrayUtils.toString( array ) );
System.out.println( "Reversed: " + ArrayUtils.toString( reversed ) );

The array is cloned and reversed, and the contents of the original and the reversed array are displayed as output using ArrayUtils.toString( ):

Original: { 1, 3, 2, 3, 5, 6 }
Reversed: { 6, 5, 3, 2, 3, 1 }

Discussion

In Example 1-5, clone( ) returns a reference to a new array, and reverse( ) operates on the array reference supplied as a parameter. It is important to realize that while clone( ) leaves the original array alone, reverse( ) operates directly on the supplied array. In addition to supporting all primitive arrays, ArrayUtils.clone( ) and ArrayUtils.reverse( ) work with object arrays. If array had been an array of Long objects, the code would bear a striking resemblance to the previous example.

The only difference between Examples Example 1-6 and Example 1-5 is the type of array being cloned and reversed. Again, ArrayUtils.toString( ) is used to print out the contents of both the original and the reverse array:

Original: { 3, 56, 233 }
Reversed: { 233, 56, 3 }

Example 1-6. Cloning and reversing an Object[ ] with ArrayUtils

Long[] array = new Long[] { new Long(3), new Long(56), new Long(233) };
Long[] reversed = ArrayUtils.clone( array );
ArrayUtils.reverse( reversed );

System.out.println( "Original: " + ArrayUtils.toString( array ) );
System.out.println( "Reversed: " + ArrayUtils.toString( reversed ) );

Without the aid of ArrayUtils.clone( ) and ArrayUtils.reverse( ), this task would have involved writing a loop to populate a reversed array. The following code completes the same task, but, in order to reverse an array, this example assigns the values from the original array in reverse; elements are inserted starting at reversed[reversed.length - 1] and ending at reversed[0]:

// readTemps returns a 1000 member double[]
double[] temperature = readTemps( );

double[] reversed = new double[temperature.length];
for( int i = 0; i < temperature.length; i++ ) {
    reversed[reversed.length - (i+1)] = temperature[i];
}

Another option is the use of the Collections.reverse() method. J2SE contains a Collections object with a static reverse() method, but this only operates on a List object. If you had an array of double primitives, and you wanted to take advantage of the Collections class, you would need to convert your double array to a list. Without Java 1.5’s autoboxing feature, a double[] will need to be translated into a Double[] before elements can be used to populate a list:

double[] temps = readTemps( );

List tempList = new ArrayList( );
for( int i = 0; i < temps.length; i++ ) {
    tempList.add( new Double[temps[i]] );
}

Collections.reverse( tempList );

double[] reversed = new double( tempList.size( ) );
Iterator i = tempList.iterator( );
int index = 0;
while( i.hasNext( ) ) {
    reversed[index] = ((Double) i.next( )).doubleValue( );
    index++;
}

That nasty translation between a double array and a list of Double objects complicates your code. The next recipe will touch upon an easier method for performing this translation.

Is ArrayUtils.clone( ) really necessary? All arrays have a clone( ) method, and all Java arrays implement Cloneable and Serializable, but I would be surprised if many Java developers have read the relevant section of the Java Language Specification (JLS), which discusses Array Members (section 10.7). All arrays can be cloned by calling the clone( ) method:

long[] temps = readTemps( );
long[] cloned = (long[]) temps.clone( );

ArrayUtils.clone( ) doesn’t provide you with any performance benefits, it doesn’t necessarily improve your code, and one could debate the assertion that it makes for more readable code. But, mainly, it exists as a safe way to handle null array references. If you attempt to clone a null reference, this utility will return a null instead of throwing a runtime exception.

Get Jakarta Commons Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.