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
а затем добавить новые списки в оригинал.