0

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?

2
  • firstForm and modify are references to the same 2D array, when one changes so does the other. If you tried with clone and it didn't work, you haven't tried properly. Btw final firstForm only means that you can't change the value firstForm as a reference not its contents through methods like setValue. Commented Feb 9, 2014 at 14:34
  • I don't know how to do it more properly :P I have just changed the line {this.modify = firstForm;} to {this.modify = firstForm.clone();} and {this.firstForm = firstForm;} to {this.firstForm = firstForm.clone();} and the result stays the same Commented Feb 9, 2014 at 14:39

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I have already done something like that (look at the last part of my question). And I think it should be correct like that, but the problem stays.
@Nexxurs yeah sorry the problem is exactly what I decribed.. the clone() method will only copy the references of the array - but the array contains references to one dimentional arrays!!
0

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.

1 Comment

I know, but I think I have prevented that problem with the .clone() function. What can I do about it?
0

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.

3 Comments

ok, I think my eclipse has a huge problem. I have tried your for-loop and I know the length of my Array (9, I already checked it with my console) But when I start my loop, I get an error, because I am out of Bounds. The Program tries to use i=9 (which is obviously impossible), although I have written i<9 and no i<=9!
it should be ++j in the second loop!
Yeah, sorry about that :) I was rushing and made a silly :P Fixed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.