У меня есть 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]]
Но когда я использую метод remove в форме:
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" второго индекса?
Это связано с тем, что вы храните тот же экземпляр ArrayList
во внешнем ArrayList
:
outerList = [instance1, instance2, instance2, instance2, ...]
Когда вы удаляете 1-й элемент из экземпляра2, изменение отображается во всех других индексах.
Если вы хотите избежать этой проблемы, вы должны создать новый экземпляр для каждого суб-списка и скопировать элементы из исходного списка.
Вероятно, matrix
содержит несколько ссылок на один и тот же ArrayList
(содержащий [1, 2, 3, 4, 5, 6, 7, 8, 9]).
Здесь вы столкнулись с различием между ссылками и примерами.
Когда вы добавили дочерний ArrayList
в первый, то, что вы на самом деле делаете, это сохранить ссылку в списке, эта ссылка затем указывает на ArrayList
.
Обратите внимание, что его даже юридический (но определенно не рекомендованный) для ArrayList
с нужным типом (например, ArrayList<?>
) ArrayList<?>
иметь ссылку на себя, вставленную в список!
Если вы храните один и тот же ArrayList
несколько раз, он будет копировать и создавать несколько ссылок, но эти ссылки будут по-прежнему указывать на один и тот же объект.
Вам нужно создать новый ArrayList
(используя new
или что-то вроде clone()
, чтобы создать дочерние ArrayLists
а затем добавить новые списки в оригинал.