-1

I have defined an int[][] object. Because it is an object, if i send it to a method as a parameter, it will only send it's reference, so any changes to the array in the method, will influence it in the main program. So i would like to make a clone of this object inside the method, but i'm not sure how to accomplish this.

I was thinking of something like so:

private void myMethod( int[][] array )
{
    //Define our temporary array (clone)
    int[][] newArray = new int[3][3];

    //Go through the elements of the array
    for .... row = 0; row < ..; row++
        for ..... col = 0; col < ..; col++
           //Copy individual elements from one array to another
           newArray[row][col] = array[row][col];
}

but will the above code copy each element from array into newArray as value (so... a clone of the item), or just the reference?

If so, how can this be accomplished. If i were to use ArrayLists instead of int[][] objects, there is the clone() method or something like that, but i haven't got that method for int[][] objects :(

Also, if i'm not mistaken if i do this inside the method newArray = array , that will copy just the reference again, so both will point to the same int[][] object :(

P.S. I know i could just test this, but i'd like to discuss it with you guys a bit, and see what's what exactly.

AndreiBogdan
  • 10,858
  • 13
  • 58
  • 106

4 Answers4

2

but will the above code copy each element from array into newArray as value (so... a clone of the item), or just the reference?

You're copying each element of the array, and each element is an int, so you're fine. The new array will be completely independent of the original.

Note that if instead you'd done:

int[][] newArray = new int[3][];
for (int i = 0; i < 3; i++) {
    newArray[i] = array[i];
}

... then that would just have copied references to the three existing int[] arrays into newArray. But you've allocated a completely new set of arrays (one int[][] and 3x int[]) so it's all independent.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

Primitive types, such as int, are not reference types. Thus, going through all the items and copying them one by one will make a copy-by-value.

In short, your code is correct.

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • then why would these guys say otherwise? http://stackoverflow.com/questions/9644896/java-multidimensional-array-considered-a-primitive-or-an-object – AndreiBogdan Mar 13 '12 at 13:46
  • @AndreiBogdan: The array itself is a reference. That answer is correct. But each `int` item of the array is a value. – Tudor Mar 13 '12 at 13:52
1

int is a primitive type, you always pass them around as value, not as reference, so you code will indeed create a new copy of the array.

You might want to consider using Arrays.copyOf(), it may be faster.

Jakub Zaverka
  • 8,816
  • 3
  • 32
  • 48
  • then why would these guys say otherwise? http://stackoverflow.com/questions/9644896/java-multidimensional-array-considered-a-primitive-or-an-object – AndreiBogdan Mar 13 '12 at 13:46
  • 1
    int is primtive type , int[][] is't primtive type. – Sam Mar 13 '12 at 13:54
  • I am not saing that int is not a primitive type, nor am I saying that an array of primitives is primitive. I said his code creates a new copy, which it does. – Jakub Zaverka Mar 13 '12 at 14:29
1

You could use clone() on the matrix and on each array corresponding to a row in the matrix, it will work without problems because you're cloning a matrix of primitive values, like this:

int[][] matrix = new int[3][3];
// ... matrix gets filled ...
int[][] copy = matrix.clone();
for (int i = 0; i < matrix.length; i++)
    copy[i] = matrix[i].clone();

The above will create a copy matrix which is independent of matrix, meaning that you can change the values of the copy without affecting the original.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • There's no point in the first `clone()` call - given that you're going to overwrite each element, why not just use `int[][]copy = new int[3][];`? – Jon Skeet Mar 13 '12 at 14:22
  • @JonSkeet I initially had my answer like that (`int[][] copy = new int[matrix.length][]`), but changed it for using a clone() operation. I don't think there's a noticeable difference in performance with either option, it's more a matter of consistency - if it's a clone, it's a clone all over. – Óscar López Mar 13 '12 at 14:26
  • I think it's misleading as it is. You *don't* want a copy of the array references, so why write code as if you do? I think it would be much clearer without the first clone call. If you were trying to explain to someone you wanted the code to do, would you say, "Now we want to create an array of `int[]` references which are the same as the existing `int[]` references in the original array"? – Jon Skeet Mar 13 '12 at 14:27
  • I want a _clone_ of the matrix, and for me it's more clear in this way. – Óscar López Mar 13 '12 at 14:29
  • I'd say that with your current code, it will be tempting for some maintenance engineer to ask themselves, "Why are we bothering to clone the "sub"-arrays? We're already cloning the array in the previous line! Let's just get rid of that loop..." Bang. You're doing work that isn't required, which makes it look like you *want* that work to be done... which makes the purpose of the code less clear. – Jon Skeet Mar 13 '12 at 14:32
  • @JonSkeet Any maintenance engineer that says that, doesn't understand the way arrays work in Java. Besides, it's [recommended](http://www.javaworld.com/javaworld/jw-01-1999/jw-01-object.html?page=2) that you don't implement a `clone` operation using constructors, instead you should use the `clone` method from the object you're cloning. – Óscar López Mar 13 '12 at 14:39
  • That advice makes sense when there can be subclasses - it doesn't apply here, IMO. (If this were an `Object[][]` then it *might* be worth doing, as you could actually be dealing with a `String[][]`, for example.) As I say, your code explicitly calls a method where the main purpose of the method is *not* required - all you *really* want is a new array of the right size. That's exactly what that statement is meant to do, so why not do it? – Jon Skeet Mar 13 '12 at 14:47