我有两个数组列表myArrayList01和myArrayList02。我使用addAll()将myArrayList02附加到myArrayList01。据我所知,addAll()仅创建arraylist的浅表副本,即,仅将myArrayList02的引用复制到myArrayList01中。
这意味着myArrayList02元素的任何更改也将反映在myArrayList01中。但是,当我使用set方法更改列表的元素之一时,该更改不会在myArrayList01中更新。是什么原因呢?
ArrayList<StringBuilder> myArrayList01=new ArrayList<>();
myArrayList01.add(new StringBuilder("uno"));
myArrayList01.add(new StringBuilder("dos"));
myArrayList01.add(new StringBuilder("tres"));
ArrayList<StringBuilder> myArrayList02=new ArrayList<>();
myArrayList02.add(new StringBuilder("one"));
myArrayList02.add(new StringBuilder("two"));
myArrayList02.add(new StringBuilder("three"));
myArrayList01.addAll(myArrayList02);
for(StringBuilder ele:myArrayList01)
System.out.print(ele+ " ");
myArrayList02.set(1, new StringBuilder("TWO"));
System.out.println("=====================");
for(StringBuilder ele:myArrayList01)
System.out.print(ele+" ");
System.out.println(myArrayList02.get(0)==myArrayList01.get(3));
输出为:
一二三三
===================
一二三三
是
答案 0 :(得分:0)
两个ArrayList
保存对相同对象的引用。如您所见,当您使用set
时,将列表中的引用替换为另一个引用,因此未更新了另一个列表。如果您实际上修改了列表中的一个对象,它将在两个列表中均得到反映,例如:
list1.get(4).append("some text);
答案 1 :(得分:0)
addAll()
不会“创建列表的浅表副本”。它创建对要复制列表所引用的相同对象的新引用,并将它们添加到目标列表中。目标列表中的这些引用不同于原始源列表中的引用。
修改源列表时,可以更改其引用之一,但这不会影响放置到目标列表中的引用的副本。
以下描述了target.addAll(source)
之后的状态,其中源列表中包含的引用已被处理到目标列表中。
target source
+------+ +-------+ +------+
| ref +----------> Item1 | +------+ ref |
+------+ +-------+ | +------+
| ref +-------+ | +---+ ref |
+------+ | +-------+ | | +------+
| ref +-----+ +--> Item2 | | |
+------+ | +-------+ | |
| ref +--+ | | |
+------+ | | +-------+ | |
| +----> Item3 <--+ |
| +-------+ |
| |
| +-------+ |
+-------> Item4 <-----+
+-------+
我现在将source
中的一个引用修改为指向其他位置,例如
source.set(1,someOtherItem)
它对target
的内容没有影响。