仅将ArrayList作为值传递而不是引用

时间:2013-04-03 04:03:58

标签: java reference arraylist pass-by-reference

简单地说,我有一个带有ArrayList参数的方法。在方法中,我修改ArrayList的内容,仅用于与方法返回的内容相关的目的。因此,我不希望作为参数传递的ArrayList完全受到影响(即不作为引用传递)。

我尝试的所有东西都未能达到预期的效果。我需要做什么才能在方法中使用ArrayList的副本,但不能更改实际的变量?

8 个答案:

答案 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());
}