Как скопировать коллекцию?



Вопрос хоть и звучит просто, но однозначно ответить на него нельзя. У внимательного разработчика сразу возникнут вопросы по ТЗ:



🤔 Как связаны исходник и копия? Если исходная коллекция поменяется, отразится ли это на копии?

🤔 Нужна изменяемая или неизменяемая копия?



Для любой комбинации ответов у джавы есть решение:



1️⃣ Изменяемый прокси



Прокси означает, что новый объект работает с теми же ссылками, что и старый.



Изменяемый — что манипуляции с новым списком разрешены и приведут к изменениям в исходнике.



Реализация простейшая:

refList = list



2️⃣ Неизменяемый прокси



ummodifiable = Collections.unmodifiableList(list)



Методы add, remove и replace у нового списка выбрасывают исключение. Менять исходную коллекцию никто не запрещает. Все изменения отобразятся во всех прокси.



Теперь перейдём к группе "копии" (collectedList и copy). Сейчас объясню, чем они отличаются от предыдущих вариантов



Каждый список — это набор ссылок. Исходный лист можно представить так:

▫️ ref1 → Order1

▫️ ref2 → Order2

▫️ list → структура данных, которая работает со ссылками ref1 и ref2



В прокси вариантах мы работаем с тем же list и с тем же набором [ref1, ref2].



В команде "копий" создаётся новый набор ссылок на те же объекты:

▫️ ref3 → Order1

▫️ ref4 → Order2



"Копии" работают с другим набором ссылок: [ref3, ref4]. Изменение исходного набора никак не влияет на набор ссылок в "копиях".



Ну и реализации:



3️⃣ Изменяемая копия



collectedList = list.stream().collect(toList())



4️⃣ Неизменяемая копия



copy = List.copyOf(list)



Правильный ответ на вопрос перед постом: refList, ummodifiable



❗️Важно: речь идёт только о ссылках и наборах ссылок. Объекты Order не копируются и остаются теми же. Если у объекта [order:1] id изменится на 100, то во всех списках будет [order:100]



Для удобства свела все варианты в табличку: