简体   繁体   中英

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]

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)

Why is that behaviour chosen? Isn't int[][] referencing an array object, rather than just the first dimension of the array? 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. 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.

Hence clone() for arrays performs a shallow copy, so only the first dimension is cloned.

(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. 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.

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.

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 .

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?

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.

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

  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?
  2. An array in java is actually an object Is an array an object in java

Now combining 1 and 2, we know that multidimensional array in Java is just an object, which has reference of other array objects.

Something like 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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