Почему метод изменяет входной параметр (массив), несмотря на то, что я копирую его внутри метода? - PullRequest
1 голос
/ 25 апреля 2020

Я новичок в Java. У меня есть метод, который должен вернуть новый модифицированный массив. Но после выполнения кода массив, который является параметром, также изменяется. Пожалуйста, объясните, где я изменяю исходный массив. Как это можно исправить? Я в отчаянии, потому что я не понимаю, куда я передаю ссылку вместо значения.

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;
    }
}

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

System.arraycopy не делает глубокую копию; скорее это делает мелкую копию. Другими словами, он копирует ссылки и, следовательно, System.arraycopy(inpArray, 0, resultArray, 0, inpArray.length); ведет себя следующим образом:

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

и так далее ...

, что также означает

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

и так далее ...

0 голосов
/ 25 апреля 2020

Изменение:

//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 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];
}

Помимо того, что вы не создаете фактическую копию области, вы также устанавливаете каждый подмассив resultArray к длине первого элемента в inpArray. Большинство массивов будет иметь подмассивы различной длины, поэтому вы должны дать каждому подмассиву индивидуальную длину.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...