Copying arrays in Java

Copying arrays is a very frequent while programming. There are a number of ways to copy an array in java. Each of them is suited for differnt situations. But before we move, lets understand the difference between shallow copy and deep copy.


1. Shallow copy vs Deep Copy

Shallow copy is like creating a new name to refer the same array stored in the memory while a deep copy is like creating copy of each element of the array and assigning this collection a new name.

Shallow copy vs Deep copy of an array.
Shallow copy vs Deep copy of an array.

Note that examples below use:

  • Arrays.toString() to get the string representation of 1D array.
  • Arrays.deepToString() to get the string representation of 2D array.

1.1 Example : Shallow Copy

Output :

  • Although only arr1 was modified, that modification reflects on both arr1 and arr2.
  • Even the reference values of both arr1 and arr2 are the same.

1.2 Example : Deep Copy (using loop)

Output :

  • Modification in array arr1 doesn’t reflect in arr2.
  • Reference values of both arr1 and arr2 are different because they point to different memory locations.

1.3 The Table of differences

Shallow CopyDeep Copy
To make a shallow copy, you just have to assign the reference of the array to be copied to a new compatible array variable.To make a deep copy, you have to copy each array member one by one. It may be done using built-in methods or by you manually.
Only one copy of each member of the array exists. The two array names are actually two ways to reference the same array.Two copies of each member of the array exist.
Changing one array reflects on the other array variable.Changing one array has no effect on the other array.
Even reference values of both the array are same. This is because they point to the same memory location.Reference values of both the arrays are differnet because they point to different memory location. Each has its own copy of the array members.

2. Copying Arrays

There are a number of ways to make deep copy of an array.

  • Using   loops
  • Using   Object.clone() method
  • Using   System.arraycopy() method
  • Using   Arrays.copyOf() method
  • Using   Arrays.copyOfRange() method

2.1 Loops to copy an array.

We have already seen the ways to make a deep copy using a loop. Let’s take another example:

Output :

  • Modification in arr1 doesn’t reflect in arr2.
  • Notice the references of both arr1 and arr2 are different.

2.2 Object.clone() to copy an array.

This method is available to all the classes. It happens because this method is a member of the Object class which is by default inherited by all the classes.

Output :

  • Modification in arr1 doesn’t reflect in arr2.
  • Notice the references of both arr1 and arr2 are different.

Notes :

  • For using Object.clone() with non-premitive type, you have to implement the Cloneable interface and override the clone() method. If you don’t, it would result in shallow copy of the individual array members.
  • You do not need to allocate the memory for the new array. The method itself allocates memory for the data being copied.

2.3 System.arraycopy() to copy an array.

This the most efficient and flexible way to copy an array. The type signature of this method is :

The significance of each parameter is :

  • src : Array to be copied.
  • srcPos : Position inside the array where copy starts.
  • dest : Destination array.
  • destPos : Position inside the destination array from where data storage starts.
  • length : Number of elements to be copied.

Output :

  • Modification in arr1 doesn’t reflect in arr2.
  • Notice the references of both arr1 and arr2 are different.
  • Default initial values for integers inside an array is 0, for booleans it is false and for reference type it is null.

Notes about System.arraycopy():

  • While using System.arraycopy() method, you have to allocate the memory first to store data inside the array.
  • It takes the destination array as an argument.

2.4 Arrays.copyOf() to copy an array.

It is an overloaded method. For integers its definition is:

The significance of each method parameter is:

  • original : The array being copied.
  • newLength : The length of the new array.

Depending on the value of newLength three things may happen:

  1. newLength = original.length : Two arrays will be exact copy of each other.
  2. newLength < original.length : New array will hold fewer elements than original.
  3. newLength > original.length : New array will hold all elements of original and indices >= original.length will be initialized to 0.

Output :

  • Modification in arr1 doesn’t reflect in arr2.
  • Notice the references of both arr1 and arr2 are different.

Notes about Arrays.copyOf():

  • You don’t have to allocate memory for the new array. The method itself allocates memory for the data being copied.
  • It returns the copied array.
  • This method internally calls System.arraycopy().

2.5 Arrays.CopyOfRange to copy an array.

It is an overloaded method. For integers its definition is :

The significance of each method parameter is:

  • original : The array being copied.
  • from : The index from where copy starts.
  • to :  The index upto which the copy happens.

Output :

  • Modification in arr1 doesn’t reflect in arr2.
  • Notice the references of both arr1 and arr2 are different.

Notes about Arrays.copyOfRange():

  • You don’t have to allocate memory for the new array. The method itself allocates memory for the data being copied.
  • It returns the copied array.
  • This method internally calls System.arraycopy().

3. Copying 2D arrays

Depending on the need we can make a shallow or deep copy of the array. To make a shallow copy you just have to assign the reference of the original array to the new array.

To make a deep copy of the array you can make a loop and from within that loop, copy the 1D arrays using any of the above 5 techniques to copy 1D array i.e :

  • Using loop
  • using method Object.clone()
  • using method System.arraycopy()
  • using method Arrays.copyOf()
  • using method Arrays.copyOfRange()

Output :

Modification in original array arr doesn’t reflect in arr1 to arr5. They all are deep copies of arr.


3. Points to Remember

  • System.arraycopy() is a lot faster than Object.clone().
  • System.arraycopy() is used internally by both Arrays.copyOf() and Arrays.copyOfRange().
  • System.arraycopy() takes the destination array as argument while System.clone(), Arrays.copyOf() and Arrays.copyOfRange() return the copied array.
  • Of all the four methods referred above only in case of System.arraycopy() you need to allocate memory yourself. Rest three allocate memory themselves.
  • In case of non-premitive type like objects the Object.clone() method returns a shallow copy. To return a deep copy, the class has to implement the Cloneable interface and override the clone() method.