将ArrayList传递给函数会在原始ArrayList中进行更改

时间:2014-05-07 12:51:06

标签: java arraylist

我需要将相同的ArrayList从main函数传递给3个不同的函数(所有函数都在不同的类中)。

当第一个函数接收到ArrayList时,它不仅会在列表的本地副本中进行更改,而且还会修改main方法中的原始ArrayList。这表示正在对内存地址进行更改。

所以,在第一个函数中,我将收到的arraylist复制到另一个相同类型的arraylist中,使用:

for(int i=0;i<valuex.size();i++)
{
  temp1=valuex.get(i);        
  VALUE.add(temp1);
}

这是我第一次介绍这个修改但后来同样的问题恢复了。后来我制作了三个arraylist副本,并将每个副本传递给3个函数中的每一个。这也失败了。

我没有使用

clone();

因为这在一段时间后创造了同样的问题.. 请帮忙......

3 个答案:

答案 0 :(得分:1)

当您将列表的副本传递给三种方法时,您将对列表的副本的引用作为数据结构传递。但是,在内存中,这两个列表最终都指向了相同的对象。

如果您的方法正在更改列表所指向的实际对象,并且您希望避免这种情况,那么克隆列表是不够的:您还必须克隆列表中的每个对象。

顺便说一下:clone()不适合你的原因是clone()只执行列表的浅层克隆:它会创建一个全新的{内存中的{1}}实例,但是列表的组成部分仍然是与原始列表指向的对象相同的对象(在内存中)。

答案 1 :(得分:1)

您已经描述了一个浅层副本 - 您已经创建了一个新的列表,但是每个列表中都有相同的对象。

如果这对您不起作用,则表明您的方法正在修改列表对象。为避免出现这种问题,您必须执行深层复制 - 创建每个对象的副本。

例如:

List<Foo> oldList = // ...
List<Foo> newList = new ArrayList<>();
for (Foo foo : oldList) {
  Foo newFoo = new Foo(foo); // copy constructor
  newList.add(newFoo);
}

答案 2 :(得分:-3)

您可以在将其作为参数传递之前,根据现有的arrayList创建一个新的ArrayList。

List existingList = new ArrayList();
o1.m1(new ArrayList(existingList));
o2.m2(new ArrayList(existingList));
o3.m3(new ArrayList(existingList));

ArrayList contructor允许您基于现有集合创建新的ArrayList。 http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(java.util.Collection)