clone()
создает новую структуру LinkedList
и возвращает новую ссылку на первый узел.Отношение между этими двумя LinkedList
s заключается в том, что они совместно используют один и тот же узел values
.Когда вы выполняете некоторые операции add
\ remove
со старым или новым списком, эти операции не изменят другой список.Вот почему мы делаем copy
- мы не хотим изменять исходную структуру связанного списка при изменении копии.
Из LinkedList.clone
документации:
Возвращает поверхностную копиюэто LinkedList
.(Сами элементы не клонируются .) @return
поверхностная копия этого LinkedList
экземпляра
Рассмотрим пример ниже:
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;
public class LinkedListsApp {
public static void main(String[] args) throws Exception {
LinkedList<AtomicInteger> l1 = new LinkedList<>();
l1.add(new AtomicInteger(100));
l1.add(new AtomicInteger(200));
LinkedList<AtomicInteger> l2 = (LinkedList) l1.clone();
l2.add(new AtomicInteger(300));
System.out.println(l1);
System.out.println(l2);
// change element on first list
l1.get(0).incrementAndGet();
System.out.println();
System.out.println("After change internal state of first element");
System.out.println(l1);
System.out.println(l2);
}
}
вышеКод печатает:
[100, 200]
[100, 200, 300]
After change internal state of first element
[101, 200]
[101, 200, 300]
Как мы видим, когда мы меняем внутреннее состояние первого элемента из первого списка, оно также видно и для второго списка.Таким образом, нет глубокой копии каждого значения элемента, а есть копия структуры - копия узлов и порядок.
Чтобы сделать это абсолютно ясным, давайте посмотрим на реализацию в Java 8
:
public Object clone() {
LinkedList<E> clone = superClone();
// Put clone into "virgin" state
clone.first = clone.last = null;
clone.size = 0;
clone.modCount = 0;
// Initialize clone with our elements
for (Node<E> x = first; x != null; x = x.next)
clone.add(x.item);
return clone;
}
Посмотрите на петлю for-each
.Он перебирает исходный список и добавляет значения в список clone
.Метод add
создает новый объект Node
, в котором хранится то же значение, что и в исходном списке: x.item
.