Клонирование списка массивов в Java с помощью конструктора

#java #arraylist #collections

#java #arraylist #Коллекции

Вопрос:

Я изучаю Java от Udemy, и инструктор написал следующий код…

Вот театр.seat — это ArrayList объекта Seat, который является внутренним классом класса Theatre. seatCopy — это копия theatre.seats, полученная путем передачи theatre.seats в его конструкторе. pritnList предназначен только для печати списка на консоли.

 List<Theatre.Seat> seatCopy = new ArrayList<>(theatre.seats);

Collections.shuffle(seatCopy);
System.out.println("Printing seat copy : ");
printList(seatCopy);
System.out.println("Printing theatre.seat : ");
printList(theatre.seats);
 

Поскольку это мелкая копия, т.Е. И seatCopy, и theatre.seats ссылаются на один и тот же объект ArrayList, то при вызове метода shuffle в seatCopy не следует ли перетасовывать и печатать оба списка одинаково?

Ниже приведен вывод:

введите описание изображения здесь

seatCopy перетасовывается, а theatre.seats — нет. Почему ?

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

1. Пожалуйста, не публикуйте изображения. Предоставьте вывод в вашем вопросе таким образом, чтобы он был доступен для чтения.

2. извините! Я позабочусь о будущих вопросах

Ответ №1:

A List содержит ссылки, а не объекты

Ваши Theatre.Seat объекты на самом деле не находятся внутри списка. A List содержит ссылки (указатели, адреса памяти) на объекты. Каждый из этих объектов seat фактически перемещается в другом месте в памяти.

Представьте места (сравните их с объектами) в разных местах вашего дома (сравните с памятью). И представьте шкаф, содержащий много пустых полок, этот шкаф является вашим List . Назначение места в списке похоже на прикрепление куска шнура к одному из стульев за обеденным столом, а другой конец шнура прикрепите к первой полке в шкафу. Затем вы прикрепляете свое мягкое кресло для просмотра телевизора другим шнуром ко второй полке в шкафу, назначая второй элемент вашему списку.

Мы говорим, что шкаф (список) содержит два стула (объекта). Но на самом деле мы имеем в виду, что список содержит две строки (ссылки), которые приводят нас к каждому стулу (объекту). Другие полки в нашем шкафу без какого-либо шнура null .

Когда вы копируете список (мелкая копия), вы не копируете объекты. Вы создаете еще один шкаф с пустыми полками, а затем подключаете второй набор шнуров. Различные места в вашем доме не дублируются. Но теперь у вас есть два набора шнуров.

Ответ №2:

Они не ссылаются на один и тот же ArrayList.

Это 2 экземпляра ArrayList, оба из которых содержат одинаковые экземпляры всех элементов.

Итак, если вы внесете изменения в экземпляр элемента, они будут изменены в обоих, но если вы внесете изменения в ArrayList, это не изменит другого.

Ответ №3:

Мелкая копия списка означает, что копируется только список, но не элементы. Вы создаете другой список, но он содержит те же объекты.

Если бы вы должны были сделать, например

 List<Theatre.Seat> seatCopy = new ArrayList<>(theatre.seats);
seatCopy.get(0).placeNumber = "13A"; // modify an element in the list(s)
Collections.shuffle(seatCopy);
System.out.println("Printing seat copy : ");
printList(seatCopy);
System.out.println("Printing theatre.seat : ");
printList(theatre.seats);
 

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