简体   繁体   English

克隆多维数组

[英]Cloning multi-dimensional arrays

int[][] array = new int[][] {...}
int[][] clone = array.clone();

I naively expected this to work. 我天真地期待这个工作。 But it didn't - it cloned only the first dimension, and I had to go and clone the other dimension manually if I wanted a true clone. 但它没有 - 它只克隆了第一个维度,如果我想要一个真正的克隆,我必须手动克隆另一个维度。 Note: the contents were properly copied. 注意:内容已正确复制。 But when I changed clone[0][1] , it reflected in array[0][1] 但是当我改变了clone[0][1] ,它反映在array[0][1]

And while .clone() is known to perform a shallow clone, int[][] looks like a single object (if we don't know its internal implementation, at least) 虽然已知.clone()执行浅层克隆,但int[][]看起来像一个单独的对象(如果我们不知道它的内部实现,至少)

Why is that behaviour chosen? 为什么选择这种行为? Isn't int[][] referencing an array object, rather than just the first dimension of the array? 是不是int[][]引用数组对象,而不仅仅是数组的第一个维度? And in what scenarios is cloning only the first dimension the desired behaviour? 在什么情况下只克隆第一个维度所需的行为?

Why is that behaviour chosen? 为什么选择这种行为?

Consistency, most likely. 一致性,最有可能。

As you say, int[][] references an array object. 如你所说, int[][]引用一个数组对象。 It just so happens that the contents of each array element is another array, but that's just a detail. 碰巧每个数组元素的内容都是另一个数组,但这只是一个细节。 Java clones all arrays identically, and since the elements can be of any type it can't guarantee to perform a deep copy. Java以相同方式克隆所有数组,并且由于元素可以是任何类型,因此无法保证执行深层复制。

Hence clone() for arrays performs a shallow copy, so only the first dimension is cloned. 因此,数组的clone()执行浅拷贝,因此只克隆第一个维度。

(In general it doesn't seem that there's a single "best" or "obvious" answer to the question of whether a clone implies deep or shallow copies. What the developer wants will depend on how each field is being used by the application, so a one-size-fits-all approach will naturally have limitations.) (一般来说,对于克隆是否暗示深拷贝或浅拷贝的问题,似乎没有单一的“最佳”或“明显”答案。开发人员想要的将取决于应用程序如何使用每个字段,因此,一刀切的方法自然会有局限性。)

This behavior is demonstrated because there is no true multi dimensional array. 由于没有真正的多维数组,因此证明了这种行为。

Java achieves multiple dimensions by making arrays of arrays. Java通过生成数组来实现多个维度。 Which means: 意思是:

int[][] is actually Array<Array<int>>

Hence the clone would only copy the first dimension. 因此,克隆只会复制第一个维度。

If you were trying with a 3 dimensional array, you would need to clone thrice. 如果您尝试使用3维数组,则需要克隆三次。

The clone method is a so called shallow copy (see another stackoverflow answer on the clone method ), which means that all the elements are copied by reference. clone方法是一个所谓的浅拷贝(请参阅clone方法的另一个stackoverflow答案 ),这意味着所有元素都是通过引用复制的。

To get to what you want (also called deep cloning) you can either copy every single array yourself using the Arrays.copy recursively, so every (sub-)array you find will get a deep-clone, or check this stackoverflow answer on deep cloning . 要获得你想要的东西(也称为深度克隆)你可以自己使用Arrays.copy复制每个单独的数组,这样你找到的每个(子)数组都会得到一个深度克隆,或者在深层检查这个stackoverflow答案克隆

Happy hacking :-) 快乐的黑客:-)

I am actually not able to replicate the behavior you have mentioned. 我实际上无法复制你提到的行为。 I can see some answers mentioning shallow copy as the root cause of the issue. 我可以看到一些答案提到浅拷贝是问题的根本原因。 Correct me if I am wrong, shallow copy just means that instead of copy of an object while cloning, we will get copy of the reference. 纠正我,如果我错了,浅拷贝只是意味着克隆时不是复制对象,我们将获得参考的副本。 A good explanation can be found here In Java, what is a shallow copy? 这里有一个很好的解释在Java中,什么是浅层副本?

In this case shallow copy will only make sure that changes in original array get reflected in the cloned array but will not stop anything from being copied. 在这种情况下,浅拷贝只会确保原始数组中的更改反映在克隆数组中,但不会阻止任何内容被复制。

int[][] array = new int[][] {{1,2,3},{4,5,6}, {7,8,9}};
int[][] clone = array.clone();

//Try this to see magic of shallow copy
//array[2][1]=11;

for(int i=0;i<array.length;i++)
    for(int j=0;j<array[i].length;j++)
        System.out.println("array["+i+"]["+j+"]"+array[i][j]);

for(int i=0;i<clone.length;i++)
    for(int j=0;j<clone[i].length;j++)
        System.out.println("clone["+i+"]["+j+"]"+clone[i][j]);

For me the cloning is done perfectly, that is both arrays have same contents. 对我来说,克隆完美无缺,即两个阵列都具有相同的内容。 The only reason I can think of for getting the issue that cloned array will not show some information is that we have actually modified original array after the cloning (shallow copy comes into play then). 我能想到克服数组的问题不会显示某些信息的唯一原因是我们在克隆之后实际修改了原始数组(然后浅拷贝进入游戏)。

BTW I used Java 1.6, I hope that is not an issue. 顺便说一句,我使用的是Java 1.6,我希望这不是问题。

Edit: If we just need to understand why their is a shallow copy instead of deep copy of a multidimensional array. 编辑:如果我们只需要理解为什么它们是浅拷贝而不是多维数组的深拷贝。 Let's look at 2 facts 让我们看看2个事实

  1. While cloning, Objects always gets cloned as shallow copy (copy of reference of the object), only native types get a real copy. 在克隆时,对象总是被克隆为浅拷贝(对象的引用副本),只有本机类型才能获得真正的副本。 In Java, what is a shallow copy? 在Java中,什么是浅拷贝?
  2. An array in java is actually an object Is an array an object in java java中的数组实际上是一个对象是一个数组,是java中的一个对象

Now combining 1 and 2, we know that multidimensional array in Java is just an object, which has reference of other array objects. 现在结合1和2,我们知道Java中的多维数组只是一个对象,它引用了其他数组对象。

Something like ArrayObj->{ArrayObj, ArrayObj, ArrayObj}; 类似于ArrayObj - > {ArrayObj,ArrayObj,ArrayObj};

And because we have Objects inside objects (composition), we are supposed to get a shallow copy as per Java cloning rule. 因为我们在对象(组合)中有对象,所以我们应该根据Java克隆规则获得浅拷贝。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM