通过set()方法更新的Arraylist不会更新引用的arraylist吗?

时间:2018-07-02 17:54:36

标签: java arraylist

我有两个数组列表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));

输出为:
一二三三
 ===================
一二三三

2 个答案:

答案 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的内容没有影响。