Aleksandr
Aleksandr

Reputation: 13

Why does the method change the input parameter (array), despite the fact that I copy it inside the method?

I'm new to Java. I have a method that should return a new modified array. But after executing the code, the array that is the parameter also changes. Please explain where I am modifying the original array. How can this be fixed? I am desperate because I don’t understand where I am passing the link instead of the value.

import java.util.Arrays;

public class question {

    public static void main(String[] args) {

        final int[][] inputArray = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        System.out.println("Original array:");
        System.out.println(Arrays.deepToString(inputArray));
        //Display
        //[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

        System.out.println("Array after delete line:");
        System.out.println(Arrays.deepToString((removeLine(1, inputArray))));
        //Display - ok
        //[[1, 2, 3], [7, 8, 9], [0, 0, 0]]


        System.out.println("The original array after using in method:");
        System.out.println(Arrays.deepToString(inputArray));
        //Display
        //[[1, 2, 3], [4, 5, 6], [0, 0, 0]]
        //I don't understand this.
    }

    static int[][] removeLine(int k, int[][] inpArray) {

        //I copy in resultArray to keep unchanged inpArray.
        int[][] resultArray = new int[inpArray.length][inpArray[0].length];
        System.arraycopy(inpArray, 0, resultArray, 0, inpArray.length);

        //I change resultArray.
        for (int i = k; i < resultArray.length - 1; i++) {
            resultArray[i] = Arrays.copyOf(resultArray[i + 1], resultArray[i + 1].length);
        }
        Arrays.fill(resultArray[resultArray.length - 1], 0);

        //I return resultArray.
        return resultArray;
    }
}

Upvotes: 1

Views: 72

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79035

System.arraycopy does not do a deep copy; rather it does a shallow copy. In other words, it copies the references and therefore System.arraycopy(inpArray, 0, resultArray, 0, inpArray.length); behaves as follows:

inpArray[0] and resultArray[0] refer to the same object
inpArray[1] and resultArray[1] refer to the same object
inpArray[2] and resultArray[2] refer to the same object

and so on...

which also means

inpArray[0] == resultArray[0] is true
inpArray[1] == resultArray[1] is true
inpArray[2] == resultArray[2] is true

and so on...

Upvotes: 1

cegredev
cegredev

Reputation: 1579

Change:

//I copy in resultArray to keep unchanged inpArray.
int[][] resultArray = new int[inpArray.length][inpArray[0].length];
System.arraycopy(inpArray, 0, resultArray, 0, inpArray.length);

to:

// I copy in resultArray to keep unchanged inpArray.
int[][] resultArray = new int[inpArray.length][];
for (int i = 0; i < inpArray.length; i++) {
    resultArray[i] = new int[inpArray[i].length];

    for (int j = 0; j < resultArray[i].length; j++)
        resultArray[i][j] = inpArray[i][j];
}

Apart from the fact that you're not creating an actual copy of the area, you're also setting every subarray of resultArray to the length of the first element in inpArray. Most arrays are going to have subarrays of differing lengths though, so you should give each subarray an individual length.

Upvotes: 0

Related Questions