Очистка подмассива без влияния на основной массив

#java #arrays #arraylist

#java #массивы #список массивов

Вопрос:

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

Вот что я написал:

         ArrayList<ArrayList<Integer>> a = new ArrayList<>();
        ArrayList<Integer> b = new ArrayList<>();
        for(int i=0;i<5;i  ) {
            b.add(r.nextInt(10));
            b.add(r.nextInt(10));
            System.out.println("B - " b);
            a.add(b);
            
            b.clear();
        }
        System.out.println(a);
  

Это мой вывод:

 B - [4, 4]
B - [3, 7]
B - [3, 7]
B - [0, 1]
A - [[], [], [], [], []]
[]
  

Не мог бы кто-нибудь, пожалуйста, исправить это и объяснить, почему это происходит?

Комментарии:

1. Не clear создавайте свой список в конце итерации цикла. Вместо этого переместите инициализацию ArrayList<Integer> b = new ArrayList<>(); внутрь цикла и избавьтесь от очистки. Вам нужно создать несколько списков вместо одного, который вы постоянно очищаете

Ответ №1:

Когда вы пишете:

 ArrayList<Integer> b = new ArrayList<>();
  

Это означает: создайте объект (сундук с сокровищами) типа ArrayList и поместите его в кучу (похороните в песке), потому что все объекты создаются там (все объекты зарыты в песок, именно так работает java). У этого объекта сейчас или когда-либо были имена (у объектов (сундуков с сокровищами) нет имен).

Затем создайте новую ссылку (бумагу, которая может содержать карту сокровищ). Установите значение ссылки так, чтобы она указывала на вновь созданный объект (нарисуйте карту места, где вы только что закопали свежесозданное сокровище в песок). Мы будем называть эту ссылку (карта сокровищ) b (в Java переменные имеют имена, а переменные непримитивных типов являются картами сокровищ. Таким образом, в то время как у treasure не может быть имени, у maps может).

Затем вы делаете:

     b.add(r.nextInt(10));
  

. Между b и add есть java-ese для: «Возьмите ссылку ‘b’, следуйте по ней и вызовите объект ‘add’ для объекта, который вы там нашли» (Возьмите карту сокровищ, которую мы назвали b , следуйте по ней и копайте. Откройте окно, запустите задание добавить то, что вы нашли). Вы должны вбить себе в голову, что . это java для того, чтобы следовать карте и копать.

Затем вы запускаете:

 a.add(b);
  

и это важнейшая часть: a это список карт сокровищ. Похоже, у вас создается впечатление, что a — это список сокровищ. В Java это невозможно, все непримитивы являются ссылками, то есть все непримитивные действия выполняются в терминах карт сокровищ, а не сокровищ.

Итак, с точки зрения сокровища, это то, что делает этот алгоритм:

  1. Создайте новый сундук с сокровищами, напишите на нем: «В этом сундуке хранятся карты сокровищ!». Закопайте его в песок, нарисуйте карту сокровищ, вызовите карту a .
  2. Создайте еще один новый сундук с сокровищами. Напишите на нем: «В этом сундуке хранятся случайные числа!». Похороните его, нарисуйте карту, вызовите ее b .
  3. Возьмите свою b карту, следуйте по ней, откройте коробку, бросьте кубик, положите кубик в коробку.
  4. Повторите # 3.
  5. Возьмите свою b карту сокровищ и сделайте ее копию. Следуйте по a карте, чтобы найти сундук с сокровищами, содержащий карту сокровищ, и поместите в него копию карты b.
  6. Возьмите свою b карту, следуйте по ней, откройте коробку, найдите кости, выбросьте их.
  7. повторите несколько раз.

Итак, в итоге у вас остается всего 2 сундука с сокровищами: один с 5 копиями точно такой же карты, все карты для поиска другого созданного вами сундука, а затем еще один сундук, в который вы кладете кучу кубиков, а затем снова выбрасываете их обратно, в результате чего он оказывается пустым.

Затем вы печатаете все это, что, естественно, подтверждает все вышесказанное: список с 5 пустыми списками.

На самом деле вы хотите каждый раз создавать новый сундук с сокровищами, а не очищать старый. Итак, возьмем:

 b.clear();
  

и замените это на:

 b = new ArrayList<Integer>();
  

т.е. вместо: «Следуйте этой карте сокровищ, найдите сундук, откройте его, удалите все кубики», вы добавляете: «Создайте совершенно новый сундук с сокровищами, закопайте его в песок, возьмите мою карту сокровищ под названием b , сотрите ее и нарисуйте карту для вновь созданного сундука, который я только что закопал. Оставьте старый сундук целым, с кубиками внутри, не трогайте это «.

Ответ №2:

Вам следует попробовать повторно инициализировать массив b вместо его очистки.