ラップトップのインターネットが機能していないため、ここにコードを配置できないため、携帯電話から投稿しています。問題は、クラス 1 とクラス 2 の 2 つのクラスがあるとします。クラス 1 にはArrayList
属性の 1 つとして があり、クラス 2 から void メソッドを呼び出し、それをArrayList
パラメーターとして渡します。そのメソッドは別のメソッドを初期化ArrayList
し、渡されたパラメーターと同じにして、その new に変更を加えますArrayList
。面白いことに、パラメーターとして渡された元の ArrayList も変更されています。考えられる理由は何ですか?
6 に答える
問題は、= を使用して新しい ArrayList を元のコピーにする場合、同じ ArrayList への新しい参照を作成しているだけだということです。同じオブジェクトを指す 2 つの変数と考えてください。
これを確認してください。何が起こっているのかを理解するのに役立つかもしれません: Javaは「参照渡し」または「値渡し」ですか?
問題を解決するには、「new」キーワードを使用して新しい ArrayList を作成し、すべてのオブジェクトを追加するか、clone() メソッドを使用する必要があります。
サンプルコード:
public class MethodArguments {
public static void main(String args[]) {
ArrayList<String> a = new ArrayList<String>();
a.add("Steve");
a.add("Daniel");
a.add("John");
a.add("Maxi");
a.add("Jeni");
System.out.println(a);
display(a);
getSize(a);
}
static void display(ArrayList<String> arrayList1) {
arrayList1.add("Pollard");
System.out.println(arrayList1); // passing the arraylist values and
// adding the element
}
static void getSize(ArrayList<String> arrayList1) {
System.out.println(arrayList1.size()); // getting the size of arraylist
// by passing arguments to
// method
}
}
出力:
[スティーブ、ダニエル、ジョン、マキシ、ジェニ]
[スティーブ、ダニエル、ジョン、マキシ、ジェニ、ポラード]
6
その理由は、ArrayList を引数として渡すと、呼び出されたメソッドが配列の内容を変更できるためです。ArrayList には、オブジェクトへの参照が含まれています。一部のクラスが ArrayList の内容を変更することを避けたい場合は、内部のすべてのオブジェクトがリスト内のオブジェクトの clone() である ArrayList のコピーを返す必要があります。
object.clone() を使用する
ArrayList clonedCopy = new ArrayList(list1.size());
for (Object obj : list1) {
clonedCopy.add(obj.clone());
}
この clonedCopy を返します。ただし、obj がクローン可能であることを確認してください。
それらは同じ参照を指しているからです。
Javaの=
演算子は、参照をコピーするだけArrayList
です(すべてのオブジェクトについても同じです)。ArrayListのディープコピーを作成するには、この回答を参照してください。
これは、新しい配列リストが同じ古い配列を指しているからです。
この小さな例はそれを明確にするはずです。
import java.util.ArrayList;
import java.util.List;
public class JavaApplication1 {
public static void main(String[] args) {
List <String> origList = new ArrayList<>();
origList.add("a");
origList.add("b");
JavaApplication1 app = new JavaApplication1();
app.addToList(origList);
for(String str:origList){
System.out.println(str);
}
}
private void addToList(List<String> strList){
System.out.println("inside addToList");
List <String> newList = new ArrayList<>();
// newList = strList; //This is how you are doing it
newList.addAll(strList); //This is how you should do it.
newList.add("x");
}
}