用构造函数在java中克隆arraylist

hjzp0vay  于 2021-07-07  发布在  Java
关注(0)|答案(3)|浏览(419)

我在udemy学习java,老师写了下面的代码。。。
这里,theather.seat是seat对象的数组列表,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对象,那么在seatcopy上调用shuffle方法时,这两个列表不应该以相同的方式进行无序排列和打印吗?
输出如下:

seatcopy被洗牌了,但theatre.seats没有。为什么?

uoifb46i

uoifb46i1#

它们引用的数组列表不同。
它们是arraylist的两个示例,都包含每个元素的相同示例。
因此,如果您对一个元素的示例进行了更改,那么这两个元素的示例都会更改,但是如果您对arraylist进行了更改,则不会更改另一个元素的示例。

mf98qq94

mf98qq942#

列表包含引用,而不是对象

你的 Theatre.Seat 对象实际上并不在列表中。一 List 保存对对象的引用(指针、内存地址)。每个座椅对象实际上都在内存中的其他位置浮动。
想象一下你家里不同地方的座位(与物体比较)(与记忆比较)。想象一个柜子里有很多空架子,那个柜子就是你的 List . 给单子分配一个座位就像把一根绳子系在一张餐桌椅上,同时把绳子的另一端系在橱柜的第一个架子上。接下来,你用另一根绳子把你的过度填充的看电视的椅子连接到橱柜的第二个架子上,给你的列表分配第二个元素。
我们说内阁(名单)有两把椅子(物品)。但我们真正的意思是,这个列表包含了两条线(引用),它们将我们引向每把椅子(对象)。我们橱柜里其他没有电线的架子是空的 null .
复制列表(浅层副本)时,您没有复制对象。您正在构建另一个空架子柜,然后连接第二组跳线。你家里的各种座位都不是重复的。但现在你有两套绳子了。

toe95027

toe950273#

列表的浅复制意味着只复制列表,而不复制元素。您确实创建了一个不同的列表,但它包含相同的对象。
举个例子,如果你要这么做的话

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);

元素的修改将出现在两个打印输出中,但是列表的顺序将不同(因为它们是不同的列表)。

相关问题