ArrayList в Arraylist удалить метод поведения

У меня есть arraylist, который выглядит как:

private ArrayList<ArrayList<Integer>> matrix = new ArrayList<ArrayList<Integer>>(9);

Он заполнен этими элементами:

[[7], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [3], [1, 2, 3, 4, 5, 6, 7, 8, 9], [4], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9]]

Теперь я хочу удалить "1" из второго индекса, поэтому мой желаемый результат:

[[7], [2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9], [3], [1, 2, 3, 4, 5, 6, 7, 8, 9], [4], [1, 2, 3, 4, 5, 6, 7, 8, 9], [9]]

Но когда я использую метод удаления в форме:

matrix.get(1).remove(0);

Выход:

[[7], [2, 3, 4, 5, 6, 7, 8, 9], [2, 3, 4, 5, 6, 7, 8, 9], [2, 3, 4, 5, 6, 7, 8, 9], [3], [2, 3, 4, 5, 6, 7, 8, 9], [4], [2, 3, 4, 5, 6, 7, 8, 9], [9]]

Вы можете видеть, что все "1" во всех ArrayLists основного ArrayList удаляются, а не только во втором индексе. Как я могу изменить свой код, чтобы удалить только "1" из второго индекса?

3 ответа

Решение

Это потому что вы храните то же самое ArrayList экземпляр во внешнем ArrayList:

outerList = [instance1, instance2, instance2, instance2, ...]

Когда вы удаляете 1-й элемент из instance2, изменения видны во всех других индексах.

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

Наверное matrix содержит несколько ссылок на один и тот же ArrayList (содержащий [1, 2, 3, 4, 5, 6, 7, 8, 9]).

Вы сталкиваетесь с разницей между ссылками и экземплярами здесь.

Когда вы добавили ребенка ArrayListВ первую очередь вы сохраняете ссылку в списке, которая затем указывает на ArrayList,

Обратите внимание, что это даже законно (но определенно не рекомендуется) для ArrayList с указанием правильного типа (например, ArrayList<?>) чтобы ссылка на себя была вставлена ​​в список!

Если вы храните то же самое ArrayList Несколько раз он скопирует и создаст несколько ссылок, но эти ссылки все равно будут указывать на один и тот же объект.

Вам нужно создать новый ArrayList (с помощью new или что-то вроде clone() для того, чтобы создать ребенка ArrayLists а затем добавить новые списки в оригинал.

Другие вопросы по тегам