JavaDevNotes.com

Java Copy Array

Array is one of the favorite data structure in Java and in other languages. It is so simple to use and easy to manipulate. And so we wish to do some operations to it from time to time. For now, we will discuss the problem of how to copy array in Java. There are two things to consider, do we want a partial copy or a full copy? For partial, we only want to copy spme items from an array, and in full copy, we wish to copy everything. Below are some examples of how to copy an array in Java.

Copy Array Using clone()

The easiest method to copy an array, if what we want is to exactly copy the entire array, is to use the clone() method of the source array Object. Here is the signature of the method:
protected Object clone()
                throws CloneNotSupportedException
The clone method comes from the Object method and it returns a copy of the original object. An array instance supports this method. Here is an example usage:
int[] src = { 100, 200, 300, 400, 500 };
int[] dst = src.clone();
System.out.println(Arrays.toString(dst));
The clone() method creates an exact copy of itself, hence the expected output is shown below:
[100, 200, 300, 400, 500]

Copy Array Using System.arraycopy()

The java.lang.System class has a static method arraycopy() that can help us perform copying of Array elements in Java. This is a very good method to choose for most purposes because of it's versatility as we can control the range of elements that will be copied from the source to destination, including position and number of items. This is the signature of the method.
public static void arraycopy(Object src,
             int srcPos,
             Object dest,
             int destPos,
             int length)
Here is the description of the parameters:
  • src - the source array.
  • srcPos - starting position in the source array.
  • dest - the destination array.
  • destPos - starting position in the destination data.
  • length - the number of array elements to be copied.
This method will copy an array from the specified source (src parameter), beginning from the specified position (srcPost parameter), to the specified position (destPost parameter) of the destination array (dest parameter). The specified number of items (length parameter) is copied from the source to the destination. Here is a simple example:
// Our source array with 5 items
int[] src = { 100, 200, 300, 400, 500 };
// 3 destination arrays with 5 items all set to 0
int[] dst1 = { 0, 0, 0, 0, 0 };
int[] dst2 = { 0, 0, 0, 0, 0 };
int[] dst3 = { 0, 0, 0, 0, 0 };
// let's copy
System.arraycopy(src, 3, dst1, 0, 2);
System.arraycopy(src, 3, dst2, 1, 2);
System.arraycopy(src, 3, dst3, 2, 2);
//let's print the results
System.out.println(Arrays.toString(dst1));
System.out.println(Arrays.toString(dst2));
System.out.println(Arrays.toString(dst3));
We copy from source arrays to the three destination arrays. For all cases, we copy from position 3 (since Java is 0 based, 3 would mean the fourth item which has the value 400), and get 2 items which would be 400 and 500. In the first destination array, we will copy to index 0 or first item. In the second destination we will copy to index 1 or second item. In the third destination we will copy to index 2 or third item. Hence, below is the output when we run the snippet.
[400, 500, 0, 0, 0]
[0, 400, 500, 0, 0]
[0, 0, 400, 500, 0]
Some pitfalls when using this method:
  • Note that both src and dest parameters can't be null otherwise NullPointerException will be thrown.
  • If src or dest is not an array, then ArrayStoreException will be thrown.
  • If src and dest are arrays of different types, then ArrayStoreException will be thrown.
  • If src is an array of primitive and dest is an array of Objects, then ArrayStoreException will be thrown.
  • If dest is an array of primitive and src is an array of Objects, then ArrayStoreException will be thrown.
  • If srcPos or destPost are negative, then IndexOutOfBoundsException will be thrown.
  • If length is negative, then IndexOutOfBoundsException will be thrown.
  • If srcPost+length is bigger than src.lenth, then IndexOutOfBoundsException will be thrown. This is because we want to copy upto the point that exceeds the src array.
  • If destPos+length is bigger than dest.length, then IndexOutOfBoundsException will be thrown. This is because we need to copy upto the point that exceeds the dest array.

Copy Array Using Arrays.copyOf

The java.util.Arrays class has a static method copyOf() that can help us perform copying from an array, returning a new array with the given length. This is the signature of the method.
public static boolean[] copyOf(boolean[] original,
               int newLength)
Here is the description of the parameters:
  • original - the array to be copied.
  • newLength - the length of the copy to be returned.
This method will return a copy of the original array, truncated or padded with elements to obtain the specified length. Here are some examples:
// Source array has 5 items
int[] src = { 100, 200, 300, 400, 500 };
// let's copy using different length
int[] dst1 = Arrays.copyOf(src, 3);
int[] dst2 = Arrays.copyOf(src, 5);
int[] dst3 = Arrays.copyOf(src, 7);
// print results
System.out.println(Arrays.toString(dst1));
System.out.println(Arrays.toString(dst2));
System.out.println(Arrays.toString(dst3));
Since the first call to copyOf is within the number of items from the original array, the first three items of the array is returned. On the second call, there are still enough items from the source, hence an array with the same contents is returned. On the third call, the new length is 7 but the original only has 5 items. The 6th and 7th items are padded with the natural default value of the array item's type. In this case, the default value for int is 0. The result of the code above is shown below:
[100, 200, 300]
[100, 200, 300, 400, 500]
[100, 200, 300, 400, 500, 0, 0]

Copy Array Using Arrays.copyOfRange()

The java.util.Arrays class has a static method copyOfRange() that can help us perform copying from a specified range of an array and returns a new array. This is the signature of the method.
public static boolean[] copyOfRange(boolean[] original,
                    int from,
                    int to)
Here is the description of the parameters:
  • original - the array from which a range is to be copied.
  • from - the initial index of the range to be copied, inclusive.
  • to - the final index of the range to be copied, exclusive.
The initial index (original) must be within the range of the array, while the final index (to) much be greater than or equal to the initial index, and also within the range of the array. This method will return a new array containing the specified range based on from and to parameters. Here is an example usage:
// Our source array with 5 items
int[] src = { 100, 200, 300, 400, 500 };
// Let's do some copying
int[] dst1 = Arrays.copyOfRange(src, 0, 2);
int[] dst2 = Arrays.copyOfRange(src, 1, 3);
int[] dst3 = Arrays.copyOfRange(src, 2, 4);
// Print the new arrays
System.out.println(Arrays.toString(dst1));
System.out.println(Arrays.toString(dst2));
System.out.println(Arrays.toString(dst3));
The behavior of this method is different from the previous way we discussed. As a new array is copied, exactly the subset of the original array is created. The first invoke of copyOfRange copies the items at index 0 and 1. The second invoke of copyOfRange copies the items at index 1 and 2. The third invoke of copyOfRange copies the items at index 2 and 3. The expected output is shown below:
[100, 200]
[200, 300]
[300, 400]

Copy Array Using Java 8 Stream API

Java 8 Stream API is good for manipulating collections that we could convert into array also. Here is a simple example of how we could use it:
Integer[] src = { 100, 200, 300, 400, 500 };
Integer[] dst = Arrays.stream(src).toArray(Integer[]::new);
System.out.println(Arrays.toString(dst));
This is a bit of an overkill as the Stream API is good for performing more complex operations on Collections. But Java 8 Stream API can still copy an array.