我正在使用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);
在这种情况下:
add()
或addAll()
功能没有任何问题,但对于某些屏幕,如果在列表a2
上进行更改,则会影响{{1}列表。 a1
接口)用于摆脱它并且工作正常。根据我的研究,Cloneable
函数仅设置对目的地列表的引用。
我的怀疑是:
add()
(仅限某些情况而非所有情况)?clone()
或add()
将列表列入另一个列表,会发生什么?addAll()
或clone()
方法是否必须add()
?addAll()
哪里不应该<?li?clone()
中进行了任何更改,会列出a1
会怎样?我的最后一个问题:
何时使用a2
或复制构造函数以及何时不需要使用。
在通用clone()
中,如果我们在目标列表中进行了如上例所示的更改,那么源列表会发生什么。
答案 0 :(得分:3)
是的,addAll
将源列表的所有引用添加到目标列表中。它不会创建这些引用引用的实例的副本。
当List包含对不可变对象的引用时,这就足够了。如果您在addAll
操作后添加或删除其中一个列表中的元素,则更改将不会反映在其他列表中。
如果List包含对可变对象的引用,并且您正在修改这些对象的状态,则必须创建副本(使用clone或复制构造函数),如果您不希望一个List中的更改反映在其他清单。
顺便说一下,将List传递给add
(而不是addAll
)会将List的引用添加到目标List。除非目标列表是列表列表,否则不应该这样做。 add
应该接受要添加到列表中的单个元素。
答案 1 :(得分:0)
听起来您想要将一个列表的对象副本添加到另一个列表中。正如Eran所说,简单地调用add()或addAll()是不够的,因为这会复制引用。
要添加到Eran的答案 - 听起来您认为调用clone()会解决您的问题,但只有在您实现了自定义克隆功能时才会这样!默认的clone()只创建一个浅表副本,这意味着克隆对象中包含的任何引用都将被复制。
一般来说,我发现复制构造函数或工厂方法比clone()更容易,更安全。