何时使用clone()以及实际上addAll()和add()的工作原理

时间:2015-07-07 13:38:34

标签: java arraylist clone

我正在使用Java和MySQL。

我的项目中有大约60个交易屏幕。我曾使用add()addAll()函数复制ArrayList

例如:

 List<Bean> a1 = new ArrayList<Bean>(); // and add some value      
 List<Bean> a2 = new ArrayList<Bean>(); 
 a2.addAll(a1);

在这种情况下:

  1. 在大多数屏幕中,add()addAll()功能没有任何问题,但对于某些屏幕,如果在列表a2上进行更改,则会影响{{1}列表。
  2. 在这些特定的屏幕中,克隆概念(实现a1接口)用于摆脱它并且工作正常。
  3. 根据我的研究,Cloneable函数仅设置对目的地列表的引用。

    我的怀疑是:

    1. 为什么需要add()(仅限某些情况而非所有情况)?
    2. 如果我们clone()add()将列表列入另一个列表,会发生什么?
    3. addAll()clone()方法是否必须add()
    4. 我们应该使用addAll()哪里不应该<?li?
    5. 如果我们在列表clone()中进行了任何更改,会列出a1会怎样?
    6. 我的最后一个问题:

      何时使用a2或复制构造函数以及何时不需要使用。 在通用clone()中,如果我们在目标列表中进行了如上例所示的更改,那么源列表会发生什么。

2 个答案:

答案 0 :(得分:3)

是的,addAll将源列表的所有引用添加到目标列表中。它不会创建这些引用引用的实例的副本。

当List包含对不可变对象的引用时,这就足够了。如果您在addAll操作后添加或删除其中一个列表中的元素,则更改将不会反映在其他列表中。

如果List包含对可变对象的引用,并且您正在修改这些对象的状态,则必须创建副本(使用clone或复制构造函数),如果您不希望一个List中的更改反映在其他清单。

顺便说一下,将List传递给add(而不是addAll)会将List的引用添加到目标List。除非目标列表是列表列表,否则不应该这样做。 add应该接受要添加到列表中的单个元素。

答案 1 :(得分:0)

听起来您想要将一个列表的对象副本添加到另一个列表中。正如Eran所说,简单地调用add()或addAll()是不够的,因为这会复制引用。

要添加到Eran的答案 - 听起来您认为调用clone()会解决您的问题,但只有在您实现了自定义克隆功能时才会这样!默认的clone()只创建一个浅表副本,这意味着克隆对象中包含的任何引用都将被复制。

一般来说,我发现复制构造函数或工厂方法比clone()更容易,更安全。