web-dev-qa-db-ja.com

ArrayListを参照としてではなく、値としてのみ渡す

簡単に言えば、ArrayListパラメーターを持つメソッドがあります。メソッドでは、メソッドによって返されるものにのみ関連する目的のために、ArrayListの内容を変更します。したがって、パラメーターとして渡されるArrayListがまったく影響を受けないようにします(つまり、参照として渡されません)。

私が試みたすべては、望ましい効果を達成するのに失敗しました。メソッド内でのみArrayListのコピーを使用できますが、実際の変数を変更しないようにするには、何をする必要がありますか?

29
fvgs

参照ではなくコピーとして配列リストを渡す方法があったとしても、それは浅いコピーにすぎません。

私は次のようなことをします:

void foo(final ArrayList list) {

    ArrayList listCopy = new ArrayList(list);
    // Rest of the code

}

コピーしたリストで作業するだけです。

42
Avi

ArrayListのコピーコンストラクターを使用して、ArrayListのコピーを作成できます。

ArrayList copy = new ArrayList(original);

ただし、リストの要素もオブジェクトである場合、コピーのメンバーを変更すると、元のメンバーも変更されることに注意する必要があります。

18
bchociej

リストの変更不可能なコピーを送信するために 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...
    }
}
_
4
Luiggi Mendoza

new ArrayList<MyObj>(old)の後でも、オブジェクトが想定されていない場所で参照を変更している理由はわかりません。そのため、内部のオブジェクトの新しいコピーをインスタンス化する必要がありました。

ArrayListのようなコピーコンストラクターを作成して、

 newArray = new ArrayList<MyObj>();
        for (int i = 0; i < oldArray.size(); i++) {
            newArray.add(new MyObj(ondArray.get(i)));
        }

私のコードのように= Pを理解するのが面倒なコードのように、Aviからの答えがあなたの場合に十分でない場合、他の誰かを助けることを願っています

3
Caio Faustino

.cloneメソッドまたはCopyOnWriteArrayListを使用してコピーを作成できます。これにより、オリジナルに影響を与えません。

3
helion3

あなたの方法でこれを試してください:

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
    }
2
Ankur Shanbhag

クローンするだけです。

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());
}
0
Parth