Reputation: 53
I have a problem and I just don't know how to solve it.
I want to make a class, where a 2D int array is saved twice. One time as final to stay like it is and one, which I can modify.
In short my class looks like this:
private static class Class {
private final int[][] firstForm;
private int[][] modify;
public Class(int[][] firstForm){
this.firstForm = firstForm;
this.modify = firstForm;
//I also already tried .clone() on both
}
public void setValue(int x, int y, int val){
if(firstForm[x][y]!=0){
System.out.println("ERROR!);
return;
}
modify[x][y]=val;
}
}
Now when I use the function setValue not only the value of modify changes, but also the one of firstForm.
I already tried with this.modify = firstForm.clone();
, but the result is the same. Can somebody please help me and tell me what I do wrong?
Upvotes: 0
Views: 80
Reputation: 26990
The problem is your misunderstanding of final
keyword.
What final
in this case does is that the variable will hold a reference that cannot be changed. However the referenced object can be changed.
Now in your code you do:
this.firstForm = firstForm;
this.modify = firstForm;
So both variables refer to the same reference, that means any changes made to the array will show in both firstForm
and modify
.
You will have to do a copy of the array. There are two kinds of copies - shallow and deep. Shallow will copy the objects of array into another array (with different reference) - this suffices for an int array. If the array would be of another object type, you would have to do a deep copy to ensure immutability.
To make a copy use two nested for-loops:
int[][] newarray = new int[firstForm.length][firstForm[0].length];
for(int i = 0; i < firstForm.length; i++){
for(int j = 0; j < firstForm[i].length; j++){
newarray[i][j] = firstForm[i][j];
}
}
Note that clone()
method does shallow copy - that means it copies the contents of the array to another array, however two dimensional array only contains references to one-dimensional arrays! That's way it won't work.
Upvotes: 3
Reputation: 41
Your problem is occurring because both of your 2D arrays are referencing the same object.
In Java, objects are passed by reference - the reference to an object is the location of that object in memory. So, when you say,
this.firstform = firstform;
this.modify = firstform;
you are actually saying "this.firstform should point to the location in memory of firstform, and so should this.modify" so they are effectively the same thing. The .clone() method should work :/ It is possible that you are not using it correctly... however, you could do it manually if you wanted to (int the constructor):
for(int i = 0; i < firstform.length; ++i)
{
for(int j = 0; j < firstform[i].length; ++j)
{
modify[i][j] = firstform[i][j];
}
}
Although this is rather ugly.
Obviously before you do the above, you will have to initialise modify to the same size in both dimensions as that of firstform.
Upvotes: 0
Reputation: 8825
You are simply copying the value of the reference to both firstForm
and modify
. What you want to do for the final
one is to copy the contents of the initial array (firstForm
), as opposed to a reference to it.
Upvotes: 0