Инициирование массива строк Java внутри и вне структуры цикла - PullRequest
2 голосов
/ 31 августа 2011

В коде ниже

    // Assume there are non-null string arrays arrayA and arrayB 

    // Code 1
    ArrayList<String[]> al = new ArrayList<String[]>();
    String[] tmpStr = new String[2];
    for (int ii = 0; ii < arrayA.length; ii++) {
            tmpStr[0] = arrayA[ii];
            tmpStr[1] = arrayB[ii];
            al.add(ii, tmpStr);
    }

    // Code 2
    ArrayList<String[]> al = new ArrayList<String[]>();

    for (int ii = 0; ii < arrayA.length; ii++) {
            String[] tmpStr = new String[2];
            tmpStr[0] = arrayA[ii];
            tmpStr[1] = arrayB[ii];
            al.add(ii, tmpStr);
    }

Код 2 дает желаемые результаты - то есть теперь все содержит {arrayA (ii), arrayB (ii)} для каждого своего индекса. Однако в коде 1 al содержит {arrayA (last_index), arrayB (last_index)} для всех своих индексов. Это почему?

Ответы [ 6 ]

5 голосов
/ 31 августа 2011

Массивы Java являются изменяемыми. Ваш код добавляет один массив несколько раз и изменяет один и тот же массив на каждой итерации.

2 голосов
/ 31 августа 2011

В первом блоке кода вы объявляете строковый массив размером 2. Таким образом, он сразу определяется в памяти, и в цикле вы присваиваете значения этой ссылке, поэтому на каждом шаге цикла его значение изменяется, и оно ' будет добавлен в объект ArrayList.

Во втором блоке кода внутри цикла вы инициализируете строковый массив, поэтому каждый раз, когда он создает новый объект массива в памяти, и все объекты будут иметь разные ссылки с различными значениями, добавленными к ним, которые будут переданы в ArrayList объект.

Вот почему вы получаете разные значения здесь.

2 голосов
/ 31 августа 2011

Возможно, вы захотите нарисовать картинку здесь.

В обоих случаях у вас есть массив с несколькими элементами. В первом случае каждый элемент массива в al указывает на один и тот же объект. Значение этого общего объекта (двухэлементный массив) продолжает записываться; в конце вашего фрагмента кода он содержит два последних присвоенных ему значения. В последнем каждый элемент массива в al указывает на совершенно другой объект. Каждый из этих объектов создается на разных проходах вашего цикла.

Попробуй. Рисование этих диаграмм очень показательно.

1 голос
/ 31 августа 2011

tmpStr[] указывает на тот же массив, который вы каждый раз создавали с помощью new String[2];. Се каждый раз, когда вы изменяете содержимое tmpStr[], оно переопределяет более ранние значения, так как массив является изменяемым.

1 голос
/ 31 августа 2011

В случае 1 вы будете создавать только массив строк. Посмотрите, сколько раз ключевое слово new используется в двух случаях. Во втором случае для каждой итерации создается несколько массивов, в первом случае создается один раз только в массиве.

0 голосов
/ 31 августа 2011

в коде 1 только после выделения памяти.и на том же массиве памяти, инициализированном дважды в одной и той же ячейке памяти.список содержит ссылку на этот массив.Он всегда будет извлекать данные из этого расположения массива, поэтому он даст последний инициализированный массив It.таким образом, мы потеряли вставленные данные.

Но в коде 2 два отдельных массива с разным расположением памяти.поэтому ссылки разные.так правильный ответ.

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