Reprinted from: Public AccountI'm a siege lion
Currently, data copying is provided in Java as follows:
- clone
Their usage is described below
1. clone method
The clone method is inherited from the Object class. The basic data types (int, boolean, char, byte, short, float, double, long) can be cloned directly using the clone method. Note that the String type is used because its value is immutable.
int type example
int[] a1 = {1, 3};
int[] a2 = ();
a1[0] = 666;
((a1)); //[666, 3]
((a2)); //[1, 3]
String type example
String[] a1 = {"a1", "a2"};
String[] a2 = ();
a1[0] = "b1"; //Change the value of elements in the a1 array
((a1)); //[b1, a2]
((a2)); //[a1, a2]
2、
The method is a local method, defined in the source code as follows:
public static native void arraycopy(Object src, int srcPos, Object dest, int desPos, int length)
The parameters are:
(Original array, the starting position of the original array, the target array, the starting position of the target array, the number of copies)
Usage example
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = new int[10];
(a1, 1, a2, 3, 3);
((a1)); // [1, 2, 3, 4, 5]
((a2)); // [0, 0, 0, 2, 3, 4, 0, 0, 0, 0]
When using this method, you need to copy to an array of allocated memory units.
3、
The underlying layer is actually used. The source code is as follows:
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) ((), newLength);
(original, 0, copy, 0,
(, newLength));
return copy;
}
Parameter meaning:
(Original array, number of copies)
Usage example:
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = (a1, 3);
((a1)) // [1, 2, 3, 4, 5]
((a2)) // [1, 2, 3]
Using this method, we do not need to use the new keyword to allocate the memory unit of the object in advance.
4、
The bottom layer is actually used, but it encapsulates a method
public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) ((), newLength);
(original, from, copy, 0,
( - from, newLength));
return copy;
}
Parameter meaning
(Original array, start position, number of copies)
Usage example:
int[] a1 = {1, 2, 3, 4, 5};
int[] a2 = (a1, 0, 1);
((a1)) // [1, 2, 3, 4, 5]
((a2)) // [1]
Finally, it should be noted that the copy of the basic type does not affect the value of the original array. If it is a reference type, it cannot be used here, because the copy of the array is a shallow copy. It is OK for the basic type, but it is not suitable for the reference type.
5. So how to achieve deep copy of objects?
5.1 Implementing the Cloneable interface
Implement the Cloneable interface and override the clone method. Note that a class does not implement this interface. It is impossible to compile and use the clone method directly.
/**
* Created by Joe on 2018/2/13.
*/
public class Dog implements Cloneable {
private String id;
private String name;
public Dog(String id, String name) {
= id;
= name;
}
//Omit getter, setter and toString methods
@Override
public Dog clone() throws CloneNotSupportedException {
Dog dog = (Dog) ();
return dog;
}
}
Example:
Dog dog1 = new Dog("1", "Dog1");
Dog dog2 = ();
("Dog1 changed");
(dog1); // Dog{id='1', name='Dog1'}
(dog2); // Dog{id='1', name='Dog1 changed'}
5.2 Combination deep copy
If another class is referenced and other classes refer to other classes, then if you want to deeply copy all classes and the referenced classes, you must implement the Cloneable interface and rewrite the clone method. This is very troublesome. The simple method is to let all objects implement the serialization interface (Serializable), and then deeply copy the object by serializing and deserializing methods.
public Dog myClone() {
Dog dog = null;
try {
//Serialize the object into a stream, because it is written in the stream as a copy of the object
//The original object is thrown in the existing JVM, so using this feature can achieve deep copy
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
(this);
//Serialize the stream into an object
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
dog = (Dog) ();
} catch (IOException | ClassNotFoundException e) {
();
}
return dog;
}
Summarize:
This article introduces several ways and usages of array copying in Java, and gives you how to implement deep copying of objects in Java. Note that unless necessary, do not use deep copying of objects in general because the performance is poor. In addition to implementing deep copy functions by yourself, there are also some open source tool classes online that also integrate these functions, such as Apache Common Lang3, but the principles are similar. Interested students can learn it by themselves.