Nexxurs
Nexxurs

Reputation: 53

Java variable saving

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

Answers (3)

Kuba Spatny
Kuba Spatny

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

mattsegers
mattsegers

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

Martin Dinov
Martin Dinov

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

Related Questions