Java-实现数组的深层和浅层副本 [英] Java - Implement deep and shallow copy of an array
问题描述
我试图理解Java中浅拷贝与深拷贝的概念. 关于该主题有很多文章和问答,但是每当我尝试在真实的Java代码中实现这些概念时,一切都变得不清楚.
I am trying to understand the concept of shallow vs deep copy in Java. There is a lot of articles and Q&A about this subject, but whenever I try to implement these concepts in a real Java code, everything become unclear to me.
我理解的答案之一是此链接,其中通过以下方式解释了深层复制和浅层复制模式.
One of the answers on which I base my understanding is in this link, where deep and shallow copying are explained via schemas.
在每种情况下,我都会在下面的实施中向您展示:
I will show you below my implementation for each case:
- 浅拷贝:
我以示例 System.arraycopy()为例,在许多文章中我读到它执行浅表复制(以及 clone 方法)>
I took for my example the method System.arraycopy() as I read in many articles that it performs a shallow copy (along with the clone method)
public class Test {
public static void main(String[] args) {
NameValue[] instance1 = {
new NameValue("name1", 1),
new NameValue("name2", 2),
new NameValue("name3", 3),
};
NameValue[] instance2 = new NameValue[instance1.length];
// Print initial state
System.out.println("Arrays before shallow copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
// Perform shallow copy
System.arraycopy(instance1, 0, instance2, 0, 3);
// Change instance 1
for (int i = 0; i < 3; i++) {
instance1[i].change();
}
// Print final state
System.out.println("Arrays after shallow copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
}
private static class NameValue {
private String name;
private int value;
public NameValue(String name, int value) {
super();
this.name = name;
this.value = value;
}
public void change() {
this.name = this.name + "-bis";
this.value = this.value + 1;
}
@Override
public String toString() {
return this.name + ": " + this.value;
}
}
}
主要方法的执行结果如下:
The result of the execution of the main methods is as follows:
Arrays before shallow copy:
Instance 1: [name1: 1, name2: 2, name3: 3]
Instance 2: [null, null, null]
Arrays after shallow copy:
Instance 1: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
Instance 2: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
此结果与上一个链接的模式一致:
this result is an accordance with the schema of the previous link:
- 深拷贝:
在本例中,我以方法 Arrays.copyOf()为例,在许多文章中我读到它执行深度复制(以及 Arrays.copyOfRange 方法)
I took for this example the method Arrays.copyOf() as I read in many articles that it performs a deep copy (along with the Arrays.copyOfRange method)
public static void main(String[] args) {
NameValue[] instance1 = {
new NameValue("name1", 1),
new NameValue("name2", 2),
new NameValue("name3", 3),
};
NameValue[] instance2 = new NameValue[instance1.length];
// Print initial state
System.out.println("Arrays before deep copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
// Perform deep copy
instance2 = Arrays.copyOf(instance1, 3);
// Change instance 1
for (int i = 0; i < 3; i++) {
instance2[i].change();
}
// Print final state
System.out.println("Arrays after deep copy:");
System.out.println("Instance 1: " + Arrays.toString(instance1));
System.out.println("Instance 2: " + Arrays.toString(instance2));
}
其中显示:
Arrays before deep copy:
Instance 1: [name1: 1, name2: 2, name3: 3]
Instance 2: [null, null, null]
Arrays after deep copy:
Instance 1: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
Instance 2: [name1-bis: 2, name2-bis: 3, name3-bis: 4]
如果我们将深层复制逻辑基于先前的架构,则应该是以下结果:
If we base the deep copy logic on the previous schema, this should be the result:
您可能会注意到,main方法的执行结果与上述架构的逻辑不同.
As you may notice, the result of the execution of the main method is different from the logic of the schema above.
欢迎任何解释.
推荐答案
我试图理解Java中浅拷贝与深拷贝的概念.
I am trying to understand the concept of shallow vs deep copy in Java.
在Java中,您传递并存储对对象的引用,而不是对象本身.
因此,当您有一个NameValue[] array
时,该数组不包含对象NameValue
,而是对这些对象的引用.
因此,当您对NameValue[] array2
进行浅表复制时,这意味着您只是将引用从一个数组复制到另一个数组.这实际上意味着,现在array
和array2
都引用完全相同的对象,并且您对array[2]
所做的任何更改都将在array2[2]
(相同的对象)中可见.
In Java you pass around and store references to objects not the objects themselves.
So when you have an NameValue[] array
the array does not contain the objects NameValue
but references to the objects.
So when you do a shallow copy to NameValue[] array2
it means you are just copying the references from one array to the other. Which effectively means that now both array
and array2
refer to exactly the same objects and any change you do from array[2]
will be visible from array2[2]
(same object).
深度复制时,将每个对象完全复制到另一个存储区,并在新数组中保留对该新对象的引用.
这样,两个数组现在引用了不同的对象,并且array2[2]
When you deep copies you copy each object completely to another memory area and you keep a reference to that new object in your new array.
This way the 2 arrays now refer to different objects and any change to array[2]
are not visible from array2[2]
更新:
这不适用于确实存储实际值而不是引用的基元.
因此,int[] a
在复制时会得到值的副本(即某种意义上的深层副本),因为a[2]
包含值本身而不是对值的引用.
Update:
This does not apply to primitives that do store the actual value and not a reference.
So an int[] a
when you copy you get a copy of the values (i.e. deep copy in a sense) because a[2]
contains the value itself and not the reference to the value.
这篇关于Java-实现数组的深层和浅层副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!