2

オブジェクトをArrayList含むがあります。(このオブジェクトはクラスであり、すべてのオブジェクトには非常に大量の情報が含まれています。正確には、これらのオブジェクトは大型の発電機を表しているため、プロパティを1つずつコピーすることはできません)。

例:

ArrayList arr = {ob1, ob2, ob3, ob4, ob5}

したがって、私がやろうとしているのは、オブジェクト(ob1)を位置5に複製することです。

arr.set(4, arr.get(0));

しかし、どういうわけか、それを行うと、ob5はコピーob ob1ではなく、ob1であるため、ob5を変更すると、ob1も変更されます。

これはArrayListsに固有のものですか?代わりにリストを使用した場合、違いはありますか?

4

9 に答える 9

2

ArrayListは参照を保存しますはい。ただし、クローンを作成することはできます(注意!ただし、浅いコピーになります-内部オブジェクトのクローンも作成されませんhttps://stackoverflow.com/a/13434779/1111527

private class JustToCheck implements Cloneable {

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

そして、このように使用します

JustToCheck ob1 = new JustToCheck();
JustToCheck ob2 = ob1;

List<JustToCheck> arr = new ArrayList<JustToCheck>();
arr.add(ob1);
arr.add(ob2);

System.out.println(arr.get(0).toString() + ": " + arr.get(1).toString());

try {
    arr.set(1, (JustToCheck) ob1.clone());
} catch (CloneNotSupportedException e) {
    e.printStackTrace();
}

System.out.println(arr.get(0).toString() + ": " + arr.get(1).toString());

出力は

example$JustToCheck@1c39a2d: example$JustToCheck@1c39a2d
example$JustToCheck@1c39a2d: example$JustToCheck@bf2d5e


PS-私は回答https://stackoverflow.com/a/13434813/1111527で問題を確認しました

不変のクラスを持つ何かがあります

Java6

String a = new String("a");
String b = a;
b += "b"; 
System.out.println("a = " + a); // a = a
System.out.println("b = " + b); // b = ab
于 2012-11-30T14:23:45.590 に答える
1

これは、ディープコピーではなくシャドウコピーを実行しているためです。

浅いコピー:浅いコピーが実行されたObj-1場合、それはコピーされますが、含まれているオブジェクトはコピーされません。含まれているオブジェクトはObj-1複製されたObj-2への変更の影響を受けます。クラスがjava.lang.Cloneableインターフェースを実装する場合、Javaはデフォルトでオブジェクトの浅いクローン作成をサポートします。Obj-2

ディープコピーobj-1示されているようにディープコピーが実行されると、obj-1だけでなく、それに含まれるオブジェクトもコピーされます。シリアル化を使用して、ディープクローニングを実現できます。シリアル化によるディープクローニングは、開発が速く、保守が容易ですが、パフォーマンスのオーバーヘッドが発生します。ソース

ディープコピーの例:

class Student implements Cloneable {
  //Contained object
  private Subject subj;
  private String name;

  public Subject getSubj() {..}
  public String getName() {..}

  public Object clone() {
    //Deep copy
    Student s = new Student(name, subj.getName());
    return s;
  }
}
于 2012-11-17T21:05:23.090 に答える
0

いいえ、Javaではオブジェクトへの参照を作成するため、ArrayListを使用せずに次のようなことを行う場合でも、次のようになります。

String a = new String("a");
String b = a;

b += "b";

aとbはどちらも「ab」に等しい。

(これからの例外はintのような基本的なタイプです(ただし、整数のインスタンスではなく、さまざまなものがあります))。

したがって、あなたの質問に対する答えはここに あります:参照ではなく値でオブジェクトをコピーする方法 とここ: http ://www.itcsolutions.eu/2010/12/29/tutorial-java-6-4-2-how -to-copy-values-of-an-array-into-another-array /

于 2012-11-17T21:09:48.023 に答える
0

リストには、オブジェクトへのポインタのみが含まれています。

ob1をob5に移動すると、ob5のポインターがあった場所にポインターを置くようにリストに指示するため、ob5へのポインターが失われ、ob1へのポインターが複製されます。

値の重複を含む他のオブジェクトを作成してから、このオブジェクトを位置4に割り当てる必要があります。

于 2012-11-17T21:10:41.530 に答える
0

オブジェクト変数は、プリミティブデータ型とは異なります。

int x = 2;
int y = x;

xとyは異なるメモリ位置を参照します。

MyClass x = new MyClass();
MyClass y = x;

xとyは同じメモリ位置を参照しますが、その位置には2つの参照があります。一方に変更を加えると、もう一方も変更されます。これを修正する方法は、メソッドを実装Cloneableして使用する.clone()ことです。

于 2012-11-17T21:11:58.300 に答える
0

shallow copying同じクラスの新しいインスタンスを作成し、すべてのフィールドを新しいインスタンスにコピーして返します。オブジェクトクラスはクローンメソッドを提供し、浅いコピーのサポートを提供します。

于 2012-11-17T21:31:24.027 に答える
0

これは、Javaのどこにでも当てはまります。 明示的に行わない限り、何もコピーされません。(実際、意図的にコピーできないオブジェクトがあります。)

于 2012-11-17T21:06:51.603 に答える
0

のコピーを作成する必要がありますElectricGenerator。最も一般的なオプションは、コピーコンストラクターの導入またはcloneメソッドの実装です。ただし、これらのソリューションは両方とも、これらすべてのプロパティをコピーする必要があります。

あなたがそれを持ったら、あなたはすることができます

//copy constructor
arr.add( new ElectricGenerator( arr.get( 0 ) ) );
//clone
arr.add( arr.get( 0 ).clone() );

別の方法は、オブジェクトをシリアル化/逆シリアル化することです

于 2012-11-17T21:08:06.610 に答える
0

これはArrayListに準拠していません。これは、Javaの機能です。新しいオブジェクトは作成されず、参照のみが渡されます。したがって、ArrayListは2つの参照を格納します。オブジェクトの.clone()メソッドを使用する必要があります。

arr.set(4, arr.get(0).clone());

これにより、オブジェクトの新しいコピーが作成されますが、このコピーは浅くなります。必要に応じて、cloneメソッドをオーバーライドしてディープコピーにする必要があります。

于 2012-11-17T21:08:39.323 に答える