简单地说,我有一个带有 ArrayList 参数的方法。在该方法中,我修改 ArrayList 的内容仅与该方法返回的内容相关。因此,我不希望作为参数传递的 ArrayList 受到影响(即不作为参考传递)。
我所尝试的一切都未能达到预期的效果。我需要做什么才能仅在方法中使用 ArrayList 的副本,而不是让它更改实际变量?
简单地说,我有一个带有 ArrayList 参数的方法。在该方法中,我修改 ArrayList 的内容仅与该方法返回的内容相关。因此,我不希望作为参数传递的 ArrayList 受到影响(即不作为参考传递)。
我所尝试的一切都未能达到预期的效果。我需要做什么才能仅在方法中使用 ArrayList 的副本,而不是让它更改实际变量?
即使您有办法将数组列表作为副本而不是通过引用传递,它也只是一个浅拷贝。
我会做类似的事情:
void foo(final ArrayList list) {
ArrayList listCopy = new ArrayList(list);
// Rest of the code
}
只需在复制的列表上工作。
您可以使用 ArrayList 的复制构造函数创建 ArrayList 的副本:
ArrayList copy = new ArrayList(original);
但是如果列表的元素也是对象,那么您必须知道修改副本的成员也会修改原始成员中的那个成员。
您可以通过Collections#unmodifiableList(yourList)
以发送列表的不可修改副本。顺便说一句,你List<Whatever>
是按值传递的,因为Java 总是按值传递,注意在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...
}
}
您可以使用该.clone
方法或 aCopyOnWriteArrayList
进行复制,从而不会影响原件。
在你的方法中试试这个:
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
}
我不确定为什么,即使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
只需克隆它。
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);
根据现有答案,但使用 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());
}