简单地说,我有一个带有ArrayList参数的方法。在方法中,我修改ArrayList的内容,仅用于与方法返回的内容相关的目的。因此,我不希望作为参数传递的ArrayList完全受到影响(即不作为引用传递)。
我尝试的所有东西都未能达到预期的效果。我需要做什么才能在方法中使用ArrayList的副本,但不能更改实际的变量?
答案 0 :(得分:38)
即使您有办法将数组列表作为副本传递而不是通过引用传递,它也只是一个浅层副本。
我会做类似的事情:
void foo(final ArrayList list) {
ArrayList listCopy = new ArrayList(list);
// Rest of the code
}
只需处理复制的列表。
答案 1 :(得分:16)
您可以使用ArrayList的复制构造函数创建ArrayList的副本:
ArrayList copy = new ArrayList(original);
但是如果列表的元素也是对象,那么您必须意识到修改副本的成员也将修改原始成员。
答案 2 :(得分:4)
您可以传递Collections#unmodifiableList(yourList)
以发送列表的不可修改副本。顺便提一下,您的List<Whatever>
按Java always pass by value后的值传递,请注意,在foo(List<Whatever> list)
方法中,您无法修改list
值,但可以修改其内容强>
public class MyClass {
List<Whatever> list = new ArrayList<Whatever>();
public void bar() {
//filling list...
foo(Collections.unmodifiableList(list));
}
public void foo(List<Whatever> list) {
//do what you want with list except modifying it...
}
}
答案 3 :(得分:3)
您可以使用.clone
方法或CopyOnWriteArrayList
制作副本,从而不会影响原作。
答案 4 :(得分:3)
我不确定为什么,即使在new ArrayList<MyObj>(old)
之后对象仍然在改变参考的地方它也不应该这样做。所以我必须在里面实例化一个新的对象副本。
我创建了一个类似于ArrayList上的复制构造函数,并且喜欢
newArray = new ArrayList<MyObj>();
for (int i = 0; i < oldArray.size(); i++) {
newArray.add(new MyObj(ondArray.get(i)));
}
如果Avi的答案在你的情况下还不够,就像我的代码太乱了甚至不理解= P
答案 5 :(得分:2)
在你的方法中试试这个:
void method(List<Integer> list) {
List copyList = new ArrayList<Integer>();
copyList.addAll(list); // This will create a copy of all the emlements of your original list
}
答案 6 :(得分:1)
只需克隆它。
public ArrayList cloneArrayList(ArrayList lst){
ArrayList list = new ArrayList();
for (int i=0; i<lst.size(); i++){
list.add(lst.get(i));
}
return list;
}
在评论中添加建议,您也可以使用
ArrayList copy = new ArrayList(original);
以及
ArrayList copy = new ArrayList();
copy.addAll(original);
答案 7 :(得分:0)
在现有答案的行上,但使用ArrayList API。您可以使用subList(fromIndex, toIndex)
方法。它显式创建了一个只包含所需元素的列表视图(当然,按顺序)。在这里,即使使用添加/删除等操作修改视图,也不会更改原始列表。它可以避免显式创建副本。
这样的事情:
public void recursiveMethod(List<Integer> list) {
if(base)
return;
recursiveCall(list);
// following will just create a tail list but will not actually modify the list
recursiveCall(list.subList(1, list.size());
}