Как изменяется Java ArrayList при передаче в качестве параметра функции, возвращающей void, и измененной в функции? Может быть перепутано с передачей по стоимости - PullRequest
1 голос
/ 27 апреля 2019

У меня есть блок кода Java, который модифицирует ArrayList, передавая ArrayList в метод, изменяя список в методе и возвращая void. Я думал, что передача по значению Java приведет к тому, что исходный ArrayList не будет изменен. Что я недопонимаю?

public class Question {

    public static void weaveLists(LinkedList<Integer> first, LinkedList<Integer> second, ArrayList<LinkedList<Integer>> results, LinkedList<Integer> prefix) {
        /* One list is empty. Add the remainder to [a cloned] prefix and
         * store result. */
        if (first.size() == 0 || second.size() == 0) {
            LinkedList<Integer> result = (LinkedList<Integer>) prefix.clone();
            result.addAll(first);
            result.addAll(second);
            results.add(result);
            return;
        }

        /* Recurse with head of first added to the prefix. Removing the
         * head will damage first, so we’ll need to put it back where we
         * found it afterwards. */
        int headFirst = first.removeFirst();
        prefix.addLast(headFirst);
        weaveLists(first, second, results, prefix);
        prefix.removeLast();
        first.addFirst(headFirst);

        /* Do the same thing with second, damaging and then restoring
         * the list.*/
        int headSecond = second.removeFirst();
        prefix.addLast(headSecond);
        weaveLists(first, second, results, prefix);
        prefix.removeLast();    
        second.addFirst(headSecond);
    }

    public static ArrayList<LinkedList<Integer>> allSequences(TreeNode node) {
        ArrayList<LinkedList<Integer>> result = new ArrayList<LinkedList<Integer>>();

        if (node == null) {
            result.add(new LinkedList<Integer>());
            return result;
        } 

        LinkedList<Integer> prefix = new LinkedList<Integer>();
        prefix.add(node.data);

        /* Recurse on left and right subtrees. */
        ArrayList<LinkedList<Integer>> leftSeq = allSequences(node.left);
        ArrayList<LinkedList<Integer>> rightSeq = allSequences(node.right);

        /* Weave together each list from the left and right sides. */
        for (LinkedList<Integer> left : leftSeq) {
            for (LinkedList<Integer> right : rightSeq) {
//This is the part I don't understand
                ArrayList<LinkedList<Integer>> weaved = new ArrayList<LinkedList<Integer>>();
                weaveLists(left, right, weaved, prefix);
                result.addAll(weaved);
            }
        }
        return result;
    }

}

Я ожидаю, что при вызове result.addAll (weaved) измененный массив не будет изменен, но после вызова weaveLists () измененный массив будет изменен, даже если он возвращает void.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2019

Чтобы ответить на вопрос вкратце - вы не понимаете, что означает передача по значению в Java .

Если вы передаете объект (списокв этом случае) и манипулировать его элементами без изменения его ссылки, это тот же объект, который вы передали, ничего не изменилось в самом объекте (списке), он имеет ту же ссылку, что и при передаче в функцию, но изменения применяются к любому изэлементы, с которыми приходится работатьрассматривается как локальная переменная, а не как пропущенная.

Проверьте топ-ответы на этот вопрос или просто прочитайте некоторые основы Java, связанные с передачей по значению.Используйте этот блог или любой другой, который вам может понравиться больше.

0 голосов
/ 27 апреля 2019

Вы создаете ссылку weaved на объект ArrayList, который хранится в памяти. При вызове оператора new тогда новый объект выделяется в памяти. Затем вы передаете ссылку weaved методу weaveLists(). Этот метод имеет ссылку result, но это только ссылка, которая ссылается на тот же объект в памяти, потому что только оператор new выделяет новую память. Таким образом, метод weaveLists() изменяет ваш исходный ArrayList. Это важная функция, которую вы должны понимать, я предлагаю вам прочитать разницу между передачей по значению и передачей по ссылке .

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