Подтвердить что ты не робот

Кажется, что массив передается по ссылке на Java, как это возможно?

Я могу опубликовать больше кода, если мне нужно, но до этого я хотел бы просто задать общий вопрос о следующем методе, в котором передается массив, а затем установить другой массив, но по какой-то причине исходный массив, тот, который проходит, также меняется, как это возможно/что я должен делать? Благодаря

tempBoard представляет собой массив такого же размера, как currentState, а temp [k] содержит изменения, которые выполняются в movePiece, текущее состояние объявлено в методе и не является глобальной переменной

private int[][] MiniMaxBaseCase(int[][] currentState, int currentColor)
{
    tempBoard = movePiece(currentState,temp[k]);
}

private int[][] movePiece(int[][] currentState, int[] move)
{
    if(move[0] == -1)
        return currentState;

    //if the piece is just moving
    if(move[4] == -1)
    {
        currentState[move[2]][move[3]] = currentState[move[0]][move[1]];
        currentState[move[0]][move[1]] = 0;
        return currentState;
    }

    //if the piece is jumping another
    if(move[4] != -1)
    {   
        currentState[move[4]][move[5]] = currentState[move[0]][move[1]];
        currentState[move[2]][move[3]] = 0;
        currentState[move[0]][move[1]] = 0;
        return currentState;
    }

    return currentState;
}
4b9b3361

Ответ 1

В Java:

  • аргументы метода действительно передаются по значению, но
  • все переменные объекта и массива в Java являются ссылочными переменными.

Чистый эффект ссылочной переменной, передаваемой по значению, заключается в том, что объект или массив, на которые указывает эта ссылочная переменная, передается по ссылке.

Ваш массив был эффективно передан по ссылке - это тот же массив.

В частности, currentState в MiniMaxBaseCase является ссылкой на массив - значение этого является ячейкой памяти массива. currentState в MiniMaxBaseCase передается значением movePiece, поэтому значение currentState в MiniMaxBaseCase (ячейка памяти), если оно скопировано в параметр currentState в movePiece - эта ссылка была передана по значению, Но теперь currentState в movePiece указывает на ту же ячейку памяти, что и currentState в MiniMaxBaseCase. Таким образом, теперь обе переменные указывают на один и тот же массив, т.е. Чистый эффект заключается в том, что массив эффективно передавался по ссылке.


Изменить: копирование многомерных массивов

Некоторые люди предлагали использовать System.arraycopy() или Array.copyOf() напрямую, не переходя в первый размер/индекс. Это не сработает.

Используйте это вместо:

public static int[][] copyOf(int[][] original) {
    int[][] copy = new int[original.length][];
    for (int i = 0; i < original.length; i++) {
        copy[i] = Arrays.copyOf(original[i]);
    }
    return copy;
}

Причина, по которой прямая копия не будет работать, заключается в том, что в Java двумерный массив действительно представляет собой массив указателей/ссылок на набор (рассеянных) одномерных массивов, т.е. int[][] представляет собой массив указателей на кучу (рассеянного) int[]. Простое выполнение System.arraycopy() или Arrays.copyOf() на двухмерном массиве будет просто копировать указатели на разбросанные массивы int[], то есть эта мелкая копия заканчивается обменом базовым набором массивов. Вы должны сделать глубокую копию, как показано в приведенном выше коде.

Некоторые ссылки:

Как сделать глубокую копию массива 2d в Java?

Да, вы должны перебирать 2D-булевский массив, чтобы глубоко скопировать его.

http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
Как скопировать многомерные массивы?

... Однако копирование двухмерного массива является более проблематичным, поскольку многомерные массивы представлены в виде массивов массивов. Это проблема, когда вы клонируете массив. System.arraycopy() предоставит вам копию ссылок на встроенные массивы....

Ответ 2

В Java нет НИКАКОГО ТАКОГО КАК ПЕРЕЗАГРУЗКА. Вы, кажется, знаете это и задаетесь вопросом, почему все еще кажется, что это то, что происходит здесь...

Ну, проблема в том, что массивы - это объекты. И объекты фактически являются Указателями. Таким образом, вы получаете COPY указателя на массив, но он все еще является массивом, на который он указывает.

Используйте System.arraycopy(), если вы хотите создать копию массива, прежде чем вносить в него какие-либо изменения.

Ответ 3

Потратьте некоторое время, чтобы хорошо прочитать это.

http://www.cs.toronto.edu/~dianeh/tutorials/params/

Перейдите к разделу "Передача массивов"

Массивы - это ссылки. Это означает, что когда мы передаем массив в качестве параметра, мы передаем его дескриптор или ссылку. Таким образом, мы можем изменить содержимое массива внутри метода.

Это из курса "148: Введение в информатику", который должен соответствовать первым двум урокам на языке Java.

Чтобы передать копию массива функции, в Java 1.6, вы можете использовать Array.copyOf, например

tempBoard = movePiece(Arrays.copyOf(currentState, currentState.length), temp[k]);

Примечание. Array.copyOf подходит только для одномерных массивов примитивов. Используемый во всем остальном, он дает вам независимый массив со всеми элементами IDENTICAL и указывает на исходный массив, будь то объекты или вложенные массивы.