0
public class SeamCarving {


public static Seam carve_seam(int[][] disruption_matrix) {
    int[][] original = disruption_matrix;
    int[][] weighted_matrix = disruption_matrix;
    SeamCarving s1 = new SeamCarving();

    weighted_matrix = s1.buildMatrix(disruption_matrix);
    ....
  }

In the above code I have a static method carve_seam. The method takes a matrix. That input is saved in a matrix variable called original. A calculation is performed on the matrix and that is also saved as a variable called weighted_matrix. Both are needed.

Since its in a static method, a new object of the class is made and it is called from that "s1.buildMatrix"

However, that line is doing something that is over my head. This is because afterwards, not only is weight_matrix changed (correctly from the buildMatrix method) but original is also changed to the same exact thing! How does this happen???

  • 2
    `int[][] weighted_matrix = disruption_matrix;` does not create an independent copy of your `disruption_matrix`, but creates a new reference that is binded to your agrument matrix. Your `disruption_matrix`, `original` and `weighted_matrix` are binded to **the exact same object**. Any attempt to modify one of those will impact the others in the same way. This is like trying to sculpt with 3 knives. Doesn't matter which one you use - the action performed by one will be visible to the others – Fureeish Nov 19 '17 at 02:52
  • Please read concept around pass by value and pass by reference. Here you are doing pass by reference but you need pass by value – recursion Nov 19 '17 at 04:10

2 Answers2

0

First thing you need to understand here is that all the three reference matrix, are referring to the same object you have passed as the input (disruption_matrix object). This is the reason why also the original and weighted_matrix are being changed. In the first line,

int[][] original=disruption_matrix;

refers to the same object in disruption_matrix.

Then on the next line,

int[][] weighted_matrix=disruption_matrix;

refers to the same old object as well. So, you do not need to reach the line,

weighted_matrix = s1.buildMatrix(disruption_matrix);

to see that both original and weighted matrix have been changed. Actually the they have been changed when you have done the calculation to the disruption_matrix itself.

This situation is quite similar to a something like, where,

int a=10;
int b=a;
int c=a;

So, not only 'a' but also 'b' and 'c' will have their value assigned to 10.

In a OOP manner, where such same object is being assigned to different references, once a change has been made to the object through a single reference no matter that you're accessing the object through a different reference, the object has been changed.

For an example let's take this simple class,

Class A{
    int val=10;
}

now, in some method we create an object and assign it to references,

A a=new A();
a.val=20;

A b=a;
b.val=30;

A c=a;
c.val=40;

As for the above code, an object is created under the reference called 'a'. In the next line, the value 'val' is accessed through that reference and has been changed from 10 to 20.

Then, the reference 'b' has been declared and it is initialized and pointed to the same object which 'a' is holding. Then in the next line, the value of that object (val) is changed again 20 to 30, but this time through 'b' instead of the reference 'a'.

Same goes to the next three lines where the value of the object is being changed from 30 to 40 through the reference 'c'.

So finally what will be the output?

System.out.println(a.val);
System.out.println(b.val);
System.out.println(c.val);

It is obviously going to give you the output,

40
40
40

This is the concept you are missing here (Pass by value and pass by reference).

Oshan Mendis
  • 186
  • 1
  • 8
0

In Java, Arrays are technically objects and not primitives, even for arrays of primitive types. Whenever you pass an argument to a method as an object, Java passes it as a reference; the values of the original argument change because all variables you have created are "referring" to the same object. This, however, is not the case with primitives, which are passed by value.

I suggest that whenever you need to make a matrix off of another you use the following utility method:

public static int[][] copyMatrix(int[][] original) {
    int[][] copy = new int[original.length][];
    for(int x = 0; x < copy.length; x++) {
        copy[x] = new int[original[x].length];
        for(int y = 0; y < copy[x].length; y++) {
            copy[x][y] = original[x][y];
        }
    }
    return copy;
}

At the end, your code would look like this:

public class SeamCarving {

    public static Seam carve_seam(int[][] disruption_matrix) {
        // no need to make an "original" variable anymore,
        // since disruption_matrix already stands for it
        int[][] weighted_matrix = copyMatrix(disruption_matrix);
        SeamCarving s1 = new SeamCarving();

        weighted_matrix = s1.buildMatrix(disruption_matrix);
        ....
    }

}

Keep in mind that this implementation copies the arrays but not the objects. This will solve your problem when working with primitives like int but not with mutable objects.

Luis Lau
  • 16
  • 1
  • 3