How to Deep Copy an Array in Java
- Understanding Deep Copy in Java
-
Deep Copy Arrays in Java Using the
System.arraycopy
Method -
Deep Copy Arrays in Java Using the
Arrays.copyOf
Method -
Deep Copy Arrays in Java Using the
clone
Method - Deep Copy Arrays in Java Using Java Streams
- Conclusion
In Java, creating a deep copy of an array is essential when you want to duplicate its content without referencing the original array. This prevents unintended modifications to the original data and ensures that changes made to one array do not affect the other.
In this article, we’ll explore various techniques for achieving deep copies of arrays in Java and discuss the strengths and considerations associated with each method.
Understanding Deep Copy in Java
A deep copy involves creating a new array and copying the contents of the original array to the new one. Unlike a shallow copy, which merely references the same objects, a deep copy creates entirely new instances of the objects within the array.
This is crucial when dealing with complex data structures or objects with internal states, as it prevents unintended side effects.
Deep Copy Arrays in Java Using the System.arraycopy
Method
The System.arraycopy
method is a utility method provided by Java to efficiently copy elements from one array to another. It allows you to specify the source array, the starting position in the source array, the destination array, the starting position in the destination array, and the total number of elements to copy.
Its syntax is as follows:
System.arraycopy(srcArray, srcPos, destArray, destPos, length);
Where:
srcArray
: The source array from which elements will be copied.srcPos
: The starting position in the source array.destArray
: The destination array where elements will be copied.destPos
: The starting position in the destination array.length
: The number of elements to be copied.
Let’s consider an example where we have an array arr1
containing integer elements. We want to create a deep copy into another array, arr2
, using System.arraycopy
.
Here’s the complete code:
import java.util.Arrays;
public class DeepCopyUsingSystemArrayCopy {
public static void main(String[] args) {
int[] arr1 = {10, 20, 30};
int[] arr2 = new int[arr1.length];
System.arraycopy(arr1, 0, arr2, 0, arr1.length);
System.out.println("Original Array (arr1): " + Arrays.toString(arr1));
System.out.println("Deep Copied Array (arr2): " + Arrays.toString(arr2));
arr2[0] = 99;
System.out.println("Modified Copied Array (arr2): " + Arrays.toString(arr2));
System.out.println("Original Array (arr1) remains unchanged: " + Arrays.toString(arr1));
}
}
In this example, we begin by defining a public class named DeepCopyUsingSystemArrayCopy
. Inside the main
method, which serves as the entry point of our program, we create an array named arr1
with elements 10
, 20
, and 30
.
To perform a deep copy, we initialize a new array arr2
with the same length as arr1
using the statement int[] arr2 = new int[arr1.length];
. This ensures that arr2
has enough space to accommodate the elements of arr1
.
The System.arraycopy
method is then utilized to perform the deep copy. It takes five arguments:
arr1
: This is the source array.0
: This is the starting position in the source array.arr2
: This is the destination array.0
: This is the starting position in the destination array.arr1.length
: This is the number of elements to copy (the length ofarr1
).
After the deep copy, we use System.out.println
to display the contents of both the original and copied arrays. We utilize Arrays.toString
to convert the array elements into a human-readable string format for printing.
Following the initial display, we modify an element in the copied array arr2
by setting arr2[0]
to 99
. This modification showcases the independence of the two arrays; changes made to arr2
do not affect the original array arr1
.
Code Output:
Original Array (arr1): [10, 20, 30]
Deep Copied Array (arr2): [10, 20, 30]
Modified Copied Array (arr2): [99, 20, 30]
Original Array (arr1) remains unchanged: [10, 20, 30]
As expected, the output confirms that the modification in arr2
doesn’t alter the contents of the original array arr1
.
Deep Copy Arrays in Java Using the Arrays.copyOf
Method
In addition to System.arraycopy
, Java provides another convenient method for deep copying arrays - Arrays.copyOf
. This method simplifies the process of creating a new array with copied elements from the original array.
Arrays.copyOf
is part of the java.util
package and is specifically designed for creating a new array with a specified length and copying elements from an existing array into it. This method is overloaded, providing variations for copying arrays of different types and accommodating situations where the new length may be different from the original array length.
The syntax is as follows:
int[] newArray = Arrays.copyOf(originalArray, length);
Where:
originalArray
: The source array from which elements will be copied.length
: The desired length of the new array.
Let’s consider an example where we have an array arr1
containing integer elements. We want to create a deep copy into another array, arr2
, using Arrays.copyOf
.
Here’s the complete Java code:
import java.util.Arrays;
public class DeepCopyUsingArraysCopyOf {
public static void main(String[] args) {
int[] arr1 = {10, 20, 30};
int[] arr2 = Arrays.copyOf(arr1, arr1.length);
System.out.println("Original Array (arr1): " + Arrays.toString(arr1));
System.out.println("Deep Copied Array (arr2): " + Arrays.toString(arr2));
arr2[0] = 99;
System.out.println("Modified Copied Array (arr2): " + Arrays.toString(arr2));
System.out.println("Original Array (arr1) remains unchanged: " + Arrays.toString(arr1));
}
}
In this example, we start by defining a public class named DeepCopyUsingArraysCopyOf
. Inside the main
method, we create an array named arr1
with elements 10
, 20
, and 30
.
To perform a deep copy, we use the Arrays.copyOf
method. This method takes the original array arr1
and its length as parameters, creating a new array arr2
with the same elements.
The deep copy ensures that modifications made to one array do not affect the other.
Following the deep copy operation, we employ System.out.println
to display the contents of both the original and copied arrays. We use Arrays.toString
to convert the array elements into a human-readable string format for printing.
After the initial display, we modify an element in the copied array arr2
by setting arr2[0]
to 99
. This modification demonstrates the independence of the two arrays; changes made to arr2
do not affect the original array arr1
.
Code Output:
Original Array (arr1): [10, 20, 30]
Deep Copied Array (arr2): [10, 20, 30]
Modified Copied Array (arr2): [99, 20, 30]
Original Array (arr1) remains unchanged: [10, 20, 30]
As expected, the output confirms that the modification in arr2
doesn’t alter the contents of the original array arr1
. This demonstration emphasizes the effectiveness of Arrays.copyOf
in achieving a deep copy.
Deep Copy Arrays in Java Using the clone
Method
Another method for achieving deep copies of arrays in Java, especially when dealing with arrays of objects, is through the use of the clone
method. This method is particularly handy when you want to create a completely independent copy of an array.
The clone
method is a member of the Object
class, and it is used to create a new object that is an exact copy of the original object. In the context of arrays, we can leverage this method to create a deep copy.
The syntax for deep copying an array of objects using clone
is as follows:
DataType[] newArray = originalArray.clone();
Here, originalArray
is the array that you want to deep copy.
Let’s consider an example where we have an array arr1
containing objects of a custom class. We want to create a deep copy into another array, arr2
, using the clone
method.
Here’s the complete code:
import java.util.Arrays;
class CustomObject {
int value;
CustomObject(int value) {
this.value = value;
}
}
public class DeepCopyUsingClone {
public static void main(String[] args) {
CustomObject[] arr1 = {new CustomObject(10), new CustomObject(20), new CustomObject(30)};
CustomObject[] arr2 = arr1.clone();
System.out.println("Original Array (arr1): " + Arrays.toString(arr1));
System.out.println("Deep Copied Array (arr2): " + Arrays.toString(arr2));
arr2[0].value = 99;
System.out.println("Modified Copied Array (arr2): " + Arrays.toString(arr2));
System.out.println("Original Array (arr1) remains unchanged: " + Arrays.toString(arr1));
}
}
In this example, we start by defining a custom class CustomObject
with a single field value
. Inside the main
method of the DeepCopyUsingClone
class, we create an array arr1
containing objects of this custom class.
To perform a deep copy, we use the clone
method on the array arr1
. This creates a new array, arr2
, that is an independent copy of arr1
.
It’s important to note that the elements within the array are still references to the same objects, so modifying the properties of these objects will affect both arrays.
After the deep copy, we employ System.out.println
to display the contents of both the original and copied arrays. We use Arrays.toString
to convert the array elements into a human-readable string format for printing.
Following the initial display, we modify the value
field of an element in the copied array arr2
. This modification showcases that, although the arrays themselves are independent, they still reference the same objects.
Therefore, changes made to the objects will be reflected in both arrays.
Code Output:
Original Array (arr1): [CustomObject@3fee733d, CustomObject@5acf9800, CustomObject@4617c264]
Deep Copied Array (arr2): [CustomObject@3fee733d, CustomObject@5acf9800, CustomObject@4617c264]
Modified Copied Array (arr2): [CustomObject@3fee733d, CustomObject@5acf9800, CustomObject@4617c264]
Original Array (arr1) remains unchanged: [CustomObject@3fee733d, CustomObject@5acf9800, CustomObject@4617c264]
As expected, the output confirms that modifying an object within arr2
also changes the corresponding object in the original array arr1
. This example illustrates the behavior of the clone
method in the context of deep copying arrays of objects.
Deep Copy Arrays in Java Using Java Streams
In Java, with the introduction of streams in Java 8, we have a concise and expressive way to perform operations on collections, including deep copying arrays.
To deep copy an array using Java Streams, we can utilize the Arrays.stream
method to convert the array into a stream, followed by the toArray
method to convert the stream back into an array. The syntax is as follows:
DataType[] newArray = Arrays.stream(originalArray).toArray(DataType[] ::new);
Here, originalArray
is the array that you want to deep copy.
To use Java Streams for deep copying arrays, we need to consider whether the array elements are mutable or immutable.
For arrays of immutable objects, the process is straightforward. For mutable objects, we may need to provide a custom copying mechanism.
Let’s consider an example where we have an array arr1
containing integer elements. We want to create a deep copy into another array, arr2
, using Java Streams.
Here’s the complete code:
import java.util.Arrays;
public class DeepCopyUsingStreams {
public static void main(String[] args) {
int[] arr1 = {10, 20, 30};
int[] arr2 = Arrays.stream(arr1).toArray();
System.out.println("Original Array (arr1): " + Arrays.toString(arr1));
System.out.println("Deep Copied Array (arr2): " + Arrays.toString(arr2));
arr2[0] = 99;
System.out.println("Modified Copied Array (arr2): " + Arrays.toString(arr2));
System.out.println("Original Array (arr1) remains unchanged: " + Arrays.toString(arr1));
}
}
In this example, we start by defining a public class named DeepCopyUsingStreams
. Inside the main
method, we create an array arr1
containing integer elements.
To perform a deep copy using Java Streams, we use the Arrays.stream
method on the original array arr1
. This converts the array into an IntStream
. We then use the toArray
method without any arguments to convert the stream back into an array, effectively creating a deep copy arr2
.
After the deep copy, we employ System.out.println
to display the contents of both the original and copied arrays. We use Arrays.toString
to convert the array elements into a human-readable string format for printing.
Following the initial display, we modify an element in the copied array arr2
. This modification showcases the independence of the two arrays; changes made to arr2
do not affect the original array arr1
.
Code Output:
Original Array (arr1): [10, 20, 30]
Deep Copied Array (arr2): [10, 20, 30]
Modified Copied Array (arr2): [99, 20, 30]
Original Array (arr1) remains unchanged: [10, 20, 30]
Conclusion
Deep copying arrays in Java is essential for maintaining data integrity and preventing unintended side effects in your programs. Each method—System.arraycopy
, Arrays.copyOf
, and Java Streams—comes with its advantages and use cases.
System.arraycopy
provides granular control over copying elements and is suitable for both shallow and deep copies. Arrays.copyOf
simplifies the process, especially when dealing with arrays of objects, offering a concise and readable solution.
Java Streams introduce a modern, functional programming paradigm, enhancing expressiveness and conciseness, which is especially beneficial when working with complex data structures.
The choice of method depends on the specific needs of your application, taking into consideration factors such as performance, readability, and the nature of the data being manipulated.
Rupam Saini is an android developer, who also works sometimes as a web developer., He likes to read books and write about various things.
LinkedIn