0

グローバル ArrayList を引数として取る多くの関数があり、それらのいくつかはこのリストを変更せず、他の関数は作業中にこの配列のいくつかの要素を削除する必要があるため、これらの関数内にローカル tempArrays を作成します。

static ArrayList array1 = new ArrayList();

public fn1(ArrayList array1)
{
   ArrayList tempArray1 = new ArrayList();
   tempArray1 = array1;
   tempArray1.remove(elemnt);
}

問題は、削除された要素が元の arrayList からも削除されるarray1ことです。理由はわかりません。.

ありがとう..

4

8 に答える 8

6

列をなして :

tempArray1 = array1;

tempArray1参照しているのと同じオブジェクトを参照する変数をArrayList作成していarray1ます。したがって、両方とも の同じオブジェクトを参照していますArrayList。いずれかの変数を使用してオブジェクトに加えられた変更は、ArrayList両方の変数に反映されます。したがって、次を使用して要素を削除する場合:

tempArray1.remove(elemnt);

array1要素の削除も反映されています。

以下を使用する必要があります。

ArrayList tempArray1 = new ArrayList(array1);

公式ドキュメントで指定されているとおりArrayList(Collection<? extends E> c)::

コレクションの反復子によって返される順序で、指定されたコレクションの要素を含むリストを構築します。

パラメータ: c -このリストに要素を配置するコレクション

于 2013-04-27T19:29:20.867 に答える
4

問題は、宣言がtempArray1 = array1;単純にtempArray1への参照を作成することarray1です。真のコピーを作成するには、次のように呼び出します。

ArrayList tempArray1 = new ArrayList(array1);
于 2013-04-27T19:29:43.143 に答える
2

次のことを試してください

List tempList = new ArrayList(oldArrayList);
于 2013-04-27T19:29:11.370 に答える
2

項目がオリジナルから削除される理由は、Java では参照型ArrayListの変数(配列、文字列、および のサブクラスであるその他のもの) が値ではなく参照を保持するためです。これが本質的に意味することは、 type の変数が、 のデータが割り当てられるメモリ アドレスを保持するということです。あなたがそうするとき、あなたは同じのアドレスを与えているだけです。これはすべて、Java から派生した型にのみ適用されます。知らなかった場合は、たまたま が含まれています。プリミティブ型 ( 、、、、、 )は値として格納されます。ObjectArrayListArrayListtempArray1 = array1;tempArray1ArrayListObjectStringbyteshortintlongcharfloatdouble

さて、あなたの本当の問題に。私は尋ねなければなりません、なぜあなたはget(index)アイテムを操作するためにメソッドを使用しないのですか?

実際に要素を削除する必要がある場合はArrayList、次のよう に のコピー コンストラクタを使用します。ArrayList tempArray1 = new ArrayList(array1);

于 2013-04-27T19:34:39.883 に答える
2

あなたが誤解している Java の特徴がいくつかあると思います。

  1. Java 変数を宣言すると、C/C++ のポインターのように、オブジェクトの参照になります。以前に作成したオブジェクトへの参照にすることも、参照する新しいオブジェクトを作成することもできます。

    //Created a new object instance on heap
    ArrayList tempArray1 = new ArrayList();
    //Both tempArray1 and tempArray2 will point to same object in memory
    ArrayList tempArray2 = tempArray1;
    

    コードでは、最初に新しいArrayListオブジェクト参照tempArray1を作成し、そのための新しいオブジェクトを作成してArrayList tempArray1 = new ArrayList();から、この参照に別の参照を割り当てtempArray1 = array1;ます。したがって、作成した最初のオブジェクトにはそれを指す参照がなく、削除されます。これで、tempArray1 と tempArray2 の両方が同じオブジェクトを指しています。

  2. Java では、オブジェクトのコピーを作成する場合、インターフェイスcloneが実装されている場合はそのメソッドを使用できます。Clonableクローン作成に関する詳細な回答については、この質問も参照してください Java でオブジェクトをコピーするにはどうすればよいですか? したがって、配列のコピーを作成したいのですが、それは間違っています。

于 2013-04-27T20:45:33.223 に答える
1

A)は、と同じインスタンスtempArray1を参照する変数です。コピーを作成するには、コピー コンストラクターを使用します。array1

List tempArray1 = new ArrayList(tempArray1);

B) メソッドからパラメーターを削除します。リストを渡す必要はありません。メソッド内のコードは既にリストにアクセスしています。実際、同じ名前のパラメーターを使用してそれを渡すことにより、元のリストを隠しています。別のリストが渡された場合、作業していると思われるリストではなく、それを使用することになります。

C) 次のように、リストを入力する必要があります。

static ArrayList<String> array1 = new ArrayList<String>();

D) 常に抽象クラスを使用します: リストに変更します:

static List<String> array1 = new ArrayList<String>();

E) リストは配列ではないので、変数 "array1" を呼び出さないでください - 誤解を招きます:

static List<String> list1 = new ArrayList<String>();
于 2013-04-27T19:53:44.700 に答える
1

作成したインスタンスをグローバルなものに置き換えています。これを試してください:

ArrayList tempArray1 = new ArrayList(array1);
tempArray1.remove(elemnt);
于 2013-04-27T19:33:16.040 に答える