gpt4 book ai didi

java - 数组的浅拷贝,为什么不能简单地做newArr = oldArr?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:42:51 27 4
gpt4 key购买 nike

假设我有一个整数数组“orig”

我想浅复制它,所以我不能这样做:

int[] shallow = orig;

我的教授说对于原语,浅拷贝和深拷贝本质上是一样的,因为我们必须复制数组的每个索引。但是将整个数组设置为另一个数组会做同样的事情,对吧?

我对对象数组有类似的问题

这是我的理念

Book[] objArr2 = objArr1;

但是我被告知我必须复制每个数组索引,比如

//for loop
objArr2[i] = objArr1[i];

对于浅拷贝,将数组等同于另一个数组和单独复制每个数组索引之间真的有什么区别吗? (我知道深度意味着你必须创建全新的对象)

最佳答案

I want to shallow copy it, so can't I just do this:

int[] shallow = orig;

那不是真正的浅拷贝。副本是与原始项目相似但不是原始项目的离散实体。在您的示例中,您实际拥有的是指向同一对象的两个引用。创建副本时,您应该有两个结果对象:原始对象和副本。

在这里,您对 shallow 所做的任何修改都会发生在 orig 上,因为它们都指向同一个对象。

当您比较的对象引用了其中的其他对象时,“浅度”就会发挥作用。例如,如果您有一个整数数组并创建了一个副本,那么您现在有两个数组都包含相同的整数值:

Original Array

[0]
[1]
[2]
[3]

After copying:

[0] <--- Original [0]
[1] [1]
[3] [2]
[4] Copy ---> [3]

但是,如果您有一个由对象组成的数组(比如 objArr1objArr2)会怎么样?当您执行浅拷贝时,您现在有两个新的数组对象,但是两个数组之间的每个对应条目都指向同一个对象(因为对象本身没有被复制;只有引用被复制了)。

Original Array:

[0:]----> [object 0]
[1:]----> [object 1]
[2:]----> [object 2]
[3:]----> [object 3]

复制后(注意相应的位置如何指向相同的实例):

Original -> [0:]----> [object 0] <----[:0] <- Copy
[1:]----> [object 1] <----[:1]
[2:]----> [object 2] <----[:2]
[3:]----> [object 3] <----[:3]

现在,如果您通过替换条目或删除条目来修改 objArr1,那么同样的事情不会发生在 objArr2 上。 但是如果您修改位于 objArr1[0] 的对象,这也会反射(reflect)在 objArr2[0] 中,因为这些位置指向 < em>相同对象。所以在这种情况下,即使容器对象本身是不同的,但它们包含的是对同一对象的引用。

当你进行深拷贝时,你会得到两个新的数组,其中每个对应的位置指向不同的实例。所以基本上你一直在复制对象。

My professor said that for primitives, shallow and deep copy are essentially the same, in that we have to copy over each index of the array.

要做出的重要区别是,当您复制基元数组时,您是在精确地复制值。每次你得到一个新的原语。然而,当您拥有一个对象数组时,您真正拥有的是一个对象引用数组。因此,当您创建一个副本时,您所做的就是创建一个 数组,其中包含原始数组中引用的副本。但是,这些引用的新副本仍然指向相同的对应对象。这就是所谓的浅拷贝。如果您对数组进行深度复制,那么每个位置所指的对象也将被复制。所以你会看到这样的东西:

Original -> [0:]----> [object 0] Copy -> [0:]----> [copy of object 0]
[1:]----> [object 1] [1:]----> [copy of object 1]
[2:]----> [object 2] [2:]----> [copy of object 2]
[3:]----> [object 3] [3:]----> [copy of object 3]

But setting the whole array equals to another array does the same thing, right?

不,它没有。您在这里所做的只是创建对现有数组的新引用:

arr1 -> [0, 1, 2, 3, 4]

现在假设您执行了 arr2 = arr1。你拥有的是:

arr1 -> [0, 1, 2, 3, 4] <- arr2

所以这里 arr1arr2 都指向同一个数组。因此,当您使用 arr2 访问数组时,您使用 arr1 执行的任何修改都会反射(reflect)出来,因为您正在查看同一个数组。复印时不会发生这种情况。

关于java - 数组的浅拷贝,为什么不能简单地做newArr = oldArr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13166884/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com