【问题标题】:create a list from another list and remove elements from copied list从另一个列表创建一个列表并从复制的列表中删除元素
【发布时间】:2013-08-28 21:34:12
【问题描述】:

假设我有以下结构并创建了一个这样的列表。 如果我这样做 temp.remove(0) 它不会影响原始列表,但 temp.get(0).vars.remove(0) 也会从原始列表中删除元素。

我认为new ArrayList(top.mids) 没有做深拷贝,那么temp.remove(0) 怎么不影响原始列表?

//Top class init part and adding elements are omitted
List<Mid> temp = new ArrayList(top.mids);
temp.remove(0);
temp.get(0).bots.remove(0);


public class Top{
    List<Mid> mids = new ArrayList<Mid>();
}

public class Mid{
    List<Bot> bots = new ArrayList<Bot>();

}

public class Bot{
    int id; 
}

【问题讨论】:

  • new ArrayList(top.mids) 正在将top.mids 中的所有内容复制到新的ArrayList。从此列表中删除并不意味着从top.mids 中删除。如果您要修改列表中的元素,这些更改将反映在 top.mids 中,因为它们引用了相同的对象。

标签: java list deep-copy shallow-copy


【解决方案1】:

是的,您的理解是正确的。 List newList = new ArrayList(collection); 会做一个浅拷贝。您可以修改newList 而不会影响原始collection,但它们都将引用相同的元素,因此如果您修改一个列表中的元素,另一个列表的元素也会得到更改。

这称为浅拷贝。这是我所描述内容的直观表示:

底部的东西是数组中的对象。

【讨论】:

    【解决方案2】:

    声明

    new ArrayList(top.mids) 没有做深拷贝

    指的是虽然您确实有一个包含旧列表中所有项目的新列表,但新列表中的项目与旧列表引用的内存实例相同。

    这意味着虽然您可以修改新列表的内容(即对对象的引用)而不会对旧列表产生任何影响,但通过旧列表访问它们时,修改该列表中的对象也将是可见的。

    为了说明这一点,我想举个例子:

    List<X> oldList = Arrays.asList(new X("1"), new X("2"));
    List<X> newList = new ArrayList<X>(oldList);
    
    newList.remove(0);
    System.out.println(newList.size()); // Prints 1
    System.out.println(oldList.size()); // Prints 2
    
    System.out.println(oldList.get(1).getValue()); // Prints 2
    newList.get(0).setValue("3");
    System.out.println(oldList.get(1).getValue()); // Prints 3
    

    【讨论】:

      猜你喜欢
      • 2022-11-13
      • 2015-09-20
      • 2016-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多