28

重複の可能性:
Java:ArrayListのクローンを作成するだけでなく、そのアイテムのクローンを作成する方法は?

次のようなサンプルプログラムがあります。

ArrayList<Invoice> orginalInvoice = new ArrayList<Invoice>();

//add some items into it here

ArrayList<Invoice> copiedInvoice = new ArrayList<Invoice>();

copiedInvoice.addAll(orginalInvoice);


内のアイテムを変更できると思いましたが、内のcopiedInvoiceこれらのアイテムには影響しませんoriginalInoice。しかし、私は間違っていました。

どうすれば別のコピー/クローンを作成できArrayListますか?

ありがとう

4

4 に答える 4

41

はい、その通りです。実装する必要があります(または、多くのプログラマーが「壊れている」と見なしているclone()、オブジェクトをコピーするための別の適切なメカニズム)。clone()メソッドclone()は、オブジェクト内のすべての可変フィールドのディープコピーを実行する必要があります。そうすれば、複製されたオブジェクトへの変更は元のオブジェクトに影響を与えません。

サンプルコードでは、秒ArrayListを作成し、同じオブジェクトへの参照を入力しています。これが、オブジェクトへの変更が両方から表示される理由Listです。クローンアプローチでは、コードは次のようになります。

List<Foo> originalList = ...;

// Create new List with same capacity as original (for efficiency).
List<Foo> copy = new ArrayList<Foo>(originalList.size());

for (Foo foo: originalList) {
  copy.add((Foo)foo.clone());
}

編集:明確にするために、上記のコードは元のオブジェクトのディープコピーを実行してListおり、新しいコードにはList元のオブジェクトのコピーへの参照が含まれています。ArrayList.clone()これは、のを実行するを呼び出すこととは対照的shallow copyですList。このコンテキストでは、浅いコピーは新しいListインスタンスを作成しますが、元のオブジェクトへの参照を含みます。

于 2009-08-25T19:00:59.770 に答える
22

可変オブジェクトをArrayListに格納する場合は、ArrayListをコピーするときに各オブジェクトをコピーする必要があります。それ以外の場合、新しいArrayListは元の参照を保持します。

ただし、不変オブジェクトを格納している場合は、次のものを使用しても問題ありません。

ArrayList copiedInvoice = new ArrayList(originalInvoice);

于 2009-08-25T19:04:06.067 に答える
3

copyedInvoice内のアイテムを変更でき、originalInoice内のこれらのテーマには影響しないと思いました。

これは、コピーされるのが参照変数であり、それ自体のオブジェクトではないために発生します。

したがって、同じオブジェクトを指す2つの「参照」ができあがります。

オブジェクト全体をコピーする必要がある場合は、クローンを作成する必要があります。

ただし、オブジェクトが他のオブジェクトである場合にオブジェクトの内部属性を複製しないと、問題が発生する可能性があります。

たとえば、次のクラス定義では問題はありません。

  public class Something {
       private int x;
       private int y;
       private String stringObject;
   }

そのコピーを作成すると、その属性の現在の値がコピーされ、それだけになります。

ただし、クラス内に別のオブジェクトがある場合は、それも複製することを検討してください。

 class OtherSomething {
        Something something;
       private int x;
 }

次の場合:

 Something shared = new Something();

 OtherSomething one = new OtherSomething();

 OtherSomething two = new OtherSomething();

 one.something = shared;
 two.something = shared;

この場合、1つと2つの両方が、同じ共有「何か」への同じ参照変数を持ち、一方の値を変更すると、もう一方に影響します。

そのため、不変オブジェクトを使用する方がはるかに簡単/優れた/簡単です。

不変オブジェクトの値を変更する必要がある場合は、正しい値で新しいオブジェクトを作成するだけです。

于 2009-08-25T19:16:20.860 に答える
-1

ByteArrayOutputStreamとByteArrayInputStreamを見てください。すべてのクラスがSerializableを実装している場合は、上記のクラスを使用してコピーを作成できます。

于 2009-08-25T19:19:35.487 に答える