0

Javaコーディングを改善したいと考えています。

ArrayListsを初期化し、次の問題を回避するための実践コードがあるかどうかについて、誰かがリンクまたは説明を提供できますか:

-1 つのクラスに 6 つの ArrayList があり、一部は他のサブセットです。一部は他のサブセットであるため、「addAll()」および「add()」メソッドを介して同じ参照を共有していることを理解しています。

その結果、サブセット内の要素を変更しようとすると、元のセットも変更されます。同じ参照を共有しているためです。私のコードは非常に面倒なので、いくつかの "get" 呼び出しで 2 つの ArrayLists がリセットされます。

このフォーラムと Google を調べましたが、必要な関連情報が見つからないようです。ArrayLists の簡単な例しか見つかりません。このフォーラムには ArrayList 参照関連の質問がいくつかあることに気付きました。この質問への回答は、将来他の人に役立つと思います。

4

2 に答える 2

1

addAllは、オブジェクトからのコピーではなく、ArrayList内のオブジェクトへの参照を追加します。コピーが必要な場合は、最初のArrayListを反復処理し、オブジェクトごとに、オブジェクトのコピーを作成する「clone」関数を呼び出して、新しいArrayListに追加する必要があります。

例:

public static void main(String[] args) {
    ArrayList<Foo> A = new ArrayList<Foo>();
    A.add(new Foo("foo1", 1));
    A.add(new Foo("foo2", 2));
    ArrayList<Foo> B = new ArrayList<Foo>();
    System.out.println("Before: ");
    System.out.println("A:");
    for(Foo foo:A){
        System.out.println(foo);
        try {
            B.add((Foo)foo.clone());
        } catch (CloneNotSupportedException ex) {
            //Never Gonna Happen
        }
    }
    System.out.println("B:");
    for(Foo foo:B){
        System.out.println(foo);
    }

    A.remove(0);

    System.out.println("After:");
    System.out.println("A:");
    for(Foo foo:A){
        System.out.println(foo);
    }
    System.out.println("B:");
    for(Foo foo:B){
        System.out.println(foo);
    }
}

public static class Foo{
    private String Name;
    private int Id;

    public Foo(String Name, int Id) {
        this.Name = Name;
        this.Id = Id;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return new Foo(Name,Id);
    }

    @Override
    public String toString() {
        return "Name: "+Name+", Id: "+Id;
    }
}

これは印刷されます:

Before: 
A:
Name: foo1, Id: 1
Name: foo2, Id: 2
B:
Name: foo1, Id: 1
Name: foo2, Id: 2
After:
A:
Name: foo2, Id: 2
B:
Name: foo1, Id: 1
Name: foo2, Id: 2

作成したクラスのArrayListを処理する場合は、それらすべてに「クローン」関数がオーバーライドされていることを確認してください。作成したクラスを含むクラスの場合は、親クラス「clone」の内部クラス用に作成した「clone」関数を使用します。等々。

于 2012-11-28T13:02:26.217 に答える