Today we will look into different ways for java array copy. Java provides inbuilt methods to copy the array. Whether you want a full copy or partial copy of the array, you can do it easily using java inbuilt classes.
Java Copy Array
There are many ways to copy array in java. Let’s look at them one by one.
Object.clone()
: Object class providesclone()
method and since array in java is also an Object, you can use this method to achieve full array copy. This method will not suit you if you want partial copy of the array.System.arraycopy()
: System classarraycopy()
is the best way to do partial copy of an array. It provides you an easy way to specify the total number of elements to copy and the source and destination array index positions. For exampleSystem.arraycopy(source, 3, destination, 2, 5)
will copy 5 elements from source to destination, beginning from 3rd index of source to 2nd index of destination.Arrays.copyOf()
: If you want to copy first few elements of an array or full copy of array, you can use this method. Obviously it’s not versatile likeSystem.arraycopy()
but it’s also not confusing and easy to use. This method internally use System arraycopy() method.Arrays.copyOfRange()
: If you want few elements of an array to be copied, where starting index is not 0, you can use this method to copy partial array. Again this method is also using System arraycopy method itself.
So these are the four most useful methods for full and partial array copy. Note that all these inbuilt methods are to copy one-dimensional arrays only.
Java Copy Array Example
Now let’s see these java array copy methods in action with a simple java program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
package com.journaldev.util; import java.util.Arrays; public class JavaArrayCopyExample { /** * This class shows different methods for copy array in java * @param args */ public static void main(String[] args) { int[] source = {1,2,3,4,5,6,7,8,9}; int[] source1 = {1,2,3}; int[] destination=null; System.out.println("Source array = "+Arrays.toString(source)); destination = copyFirstFiveFieldsOfArrayUsingSystem(source); System.out.println("Copy First five elements of array if available. Result array = "+Arrays.toString(destination)); destination = copyFirstFiveFieldsOfArrayUsingSystem(source1); System.out.println("Copy First five elements of array if available. Result array = "+Arrays.toString(destination)); destination = copyFullArrayUsingSystem(source); System.out.println("Copy full array using System.copyarray() function. Result array = "+Arrays.toString(destination)); destination = copyFullArrayUsingClone(source); System.out.println("Copy full array using clone() function. Result array = "+Arrays.toString(destination)); destination = copyFullArrayUsingArrayCopyOf(source); System.out.println("Copy full array using Arrays.copyOf() function. Result array = "+Arrays.toString(destination)); destination = copyLastThreeUsingArrayCopyOfRange(source); System.out.println("Copy last three elements using Arrays.copyOfRange() function. Result array = "+Arrays.toString(destination)); } /** * This method copy full array using Arrays.copyOf() function * @param source * @return */ private static int[] copyFullArrayUsingArrayCopyOf(int[] source) { return Arrays.copyOf(source, source.length); } /** * This method copy partial array (last 3 elements) using * Arrays.copyOfRange() function * @param source * @return */ private static int[] copyLastThreeUsingArrayCopyOfRange(int[] source) { //length check is necessary to avoid java.lang.ArrayIndexOutOfBoundsException //but for simplicity I am not doing that return Arrays.copyOfRange(source, source.length-3, source.length); } /** * This method copy full array using clone() function * @param source * @return */ private static int[] copyFullArrayUsingClone(int[] source) { return source.clone(); } /** * This method copy full array using System.arraycopy() function * @param source * @return */ private static int[] copyFullArrayUsingSystem(int[] source) { int[] temp=new int[source.length]; System.arraycopy(source, 0, temp, 0, source.length); return temp; } /** * This method copy full first five elements of array * using System.arraycopy() function * @param source * @return */ private static int[] copyFirstFiveFieldsOfArrayUsingSystem(int[] source) { if(source.length > 5){ int[] temp=new int[5]; System.arraycopy(source, 0, temp, 0, 5); return temp; }else{ int[] temp=new int[source.length]; System.arraycopy(source, 0, temp, 0, source.length); return temp; } } } |
Output of the above program is:
1 2 3 4 5 6 7 8 9 |
<span style="color: #008000;"><strong><code> Source array = [1, 2, 3, 4, 5, 6, 7, 8, 9] Copy First five elements of array if available. Result array = [1, 2, 3, 4, 5] Copy First five elements of array if available. Result array = [1, 2, 3] Copy full array using System.copyarray() function. Result array = [1, 2, 3, 4, 5, 6, 7, 8, 9] Copy full array using clone() function. Result array = [1, 2, 3, 4, 5, 6, 7, 8, 9] Copy full array using Arrays.copyOf() function. Result array = [1, 2, 3, 4, 5, 6, 7, 8, 9] Copy last three elements using Arrays.copyOfRange() function. Result array = [7, 8, 9] </code></strong></span> |
Java Array Copy – Shallow Copy
Note that all the inbuilt methods discussed above for array copy perform shallow copy, so they are good for primitive data types and immutable objects such as String. If you want to copy an array of mutable objects, you should do it by writing code for a deep copy yourself. Below is a program showing the problem with shallow copy methods.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.util.Arrays; public class JavaArrayCopyMutableObjects { public static void main(String[] args) { Employee e = new Employee("Pankaj"); Employee[] empArray1 = {e}; Employee[] empArray2 = new Employee[empArray1.length]; System.arraycopy(empArray1, 0, empArray2, 0, empArray1.length); System.out.println("empArray1 = "+Arrays.toString(empArray1)); System.out.println("empArray2 = "+Arrays.toString(empArray2)); //Let's change empArray1 empArray1[0].setName("David"); System.out.println("empArray1 = "+Arrays.toString(empArray1)); System.out.println("empArray2 = "+Arrays.toString(empArray2)); } } class Employee { private String name; public Employee(String n) { this.name = n; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return this.name; } } |
Now when we run the above program, below is the output produced.
1 2 3 4 5 6 |
<span style="color: #008000;"><strong><code> empArray1 = [Pankaj] empArray2 = [Pankaj] empArray1 = [David] empArray2 = [David] </code></strong></span> |
As you can see that empArray2
got changed too even though it was never the intention. This can cause serious issues in your application, so you are better of writing your own code for deep copying of array. Similar case is there for java object clone method.
Below is the code for full array copy to use in this case. You can easily write something like this for partial array copy too.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import java.util.Arrays; public class JavaArrayCopyMutableObjects { public static void main(String[] args) { Employee e = new Employee("Pankaj"); Employee[] empArray1 = {e}; Employee[] empArray2 = fullCopy(empArray1); System.out.println("empArray1 = "+Arrays.toString(empArray1)); System.out.println("empArray2 = "+Arrays.toString(empArray2)); //Let's change empArray1 empArray1[0].setName("David"); System.out.println("empArray1 = "+Arrays.toString(empArray1)); System.out.println("empArray2 = "+Arrays.toString(empArray2)); } private static Employee[] fullCopy(Employee[] source) { Employee[] destination = new Employee[source.length]; for(int i=0; i< source.length; i++) { Employee e = source[i]; Employee temp = new Employee(e.getName()); destination[i] = temp; } return destination; } } class Employee { private String name; public Employee(String n) { this.name = n; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return this.name; } } |
Now when we run the above program, the output produced is:
1 2 3 4 5 6 |
<span style="color: #008000;"><strong><code> empArray1 = [Pankaj] empArray2 = [Pankaj] empArray1 = [David] empArray2 = [Pankaj] </code></strong></span> |
As you can see, in deep copy our source and destination array elements are referring to different objects. So they are totally detached and if we change one of them, the other will remain unaffected.
That’s all for java copy array and how to properly do array copy in java programs.
Reference: System class arraycopy documentation