2012-02-22 9 views
2

私は2D ArrayListです。 ArrayListは、1ArrayListを含む。私は次のコードを試しました:2d arraylists in java(最終的に同じコレクションになる理由)

これは主な2D ArrayListです。ここで私はArrayListの1のコピーを作成しようとしました(selectedRowは私が取得されArrayList言うだけの数である)その後

ArrayList<Items> newList = new ArrayList<Items>(arrayList.get(selectedRow)); 

ArrayList<ArrayList<Items>> arrayList = new ArrayList<ArrayList<Items>>(); 

:メインArrayList内部ArrayListのがare10私は別のものを作成するArrayList

ArrayList<Items> changeList = new ArrayList<Items>(it.returnTheNewArrayList(newList,randomItem)); 

次に、私はこのmet hod。このメソッドの目的は、オブジェクトの1つの属性を変更することです。

public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item){ 

    int randomBin = r.nextInt(50); 

    for(Items i:a){ 

     if(item==i.itemIds()){ 

      while(randomBin==i.bins()){ 
       randomBin = r.nextInt(50); 

      } 
      i.setBin(randomBin); 

     } 

    } 
return a; 

} 

最後に、私はこれが手順で、2DのArrayList

arrayList.set(whichList, changeList); 

で新しいのArrayListを設定します。私はこの手順を実行すると、newListchangeListの両方が同じであることを確認しました。これらの両方で、私はreturnTheNewArrayListの方法で行った変更を保存しています(私はデバッグでそれを見つけました)。しかし、私は1つだけを変更したい(changeList)。

どうしたのですか?

+0

を取得するには、今度は同じオブジェクトをリストのコピーに入れます。 BTW 'Items'はクラスの奇妙な名前です。この型の1つのオブジェクトが1つのアイテムであれば、クラス 'Item'をよりよく呼び出すことができます。 –

答えて

5

リストには、オブジェクトへの参照のが含まれています。 i.setBin(...)に電話すると、おそらくオブジェクト自体に変更が加えられます。

各リストには参照の独立したコピーがあります。したがって、他のリストに影響を与えずに1つのリストから要素を削除できますが、のみの参照です。参照。

あなたは同じホームアドレスのリストを持つ2人のクリップボードを与えたとします。一人が行って、クリップボードにあるすべての家のリストの正面扉を赤く塗り、次に二人目が同じ家を訪れました。第二の人は赤い扉を見るだろうか?それはここでも同じことです。 リストには、オブジェクトではなく参照が含まれています。あなたはリストが完全に依存しないようにしたい場合は

、あなたは異なるオブジェクトへの参照でそれらを移入する必要があります。

編集:私はちょうどあなたが実際にも、最初の場所で新しいArrayListを作成していない、あなたのreturnTheNewArrayList方法を、変更する必要がありますことに気付きました!

public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item) { 
    // Stuff which doesn't change the value of a... 

    return a; 
} 

ここでも、aの値は、あなたが戻って同じ参照を返すときに、あなたがすべてで新しいArrayListを返していない...リストにちょうど参照です。

リファレンスとオブジェクトがJavaでどのように機能するかは、実際にはという重要な意味を持っています。returnTheNewArrayList方法の内部

+1

+1は既に十分だった答えを延長する時間をとってくれました。 –

+0

と 'Collections.copy(リストDEST、リストSRC)' –

+0

@TheNailを使用すると便利だろう:私は十分な注意を払っていなかったように、それは本当に、ありませんでした*重要* returnTheNewArrayList' 'の欠陥!しかし、自信の投票のためにありがとう:) –

2

、最初aのクローンを作成する必要があります。それ以外の場合は元のArrayListと元のItemsを変更します。ジョンは理由を説明する素晴らしい仕事をしたので、ここでは取り上げません。あなたはItemsクラスを自分で書いたので、あなたはCloneableインタフェースを自身で実装する必要があります、

ArrayList<Items> clone = new ArrayList<Items>(a.size()); 
for(Items item: a) clone.add(item.clone()); 

//modify clone here 

return clone; 

:あなたのコードのようなものを見ることができます。

は、クローン方法のwikipedia page詳細については、を参照してください。

+0

ここではあなたの例では:item.clone()を書いていますが、オブジェクトアイテムの場合、私はclone()メソッドを見つけることができません。 –

+0

@Alexあなたが 'Items'を自分で書いたのであれば、自分で' clone'を実装する必要があります。 – dbyrne

+0

@Alex更新の回答 – dbyrne

0

newListとチェンジが同じでない(==ではない)が、その内容は同一です。

あなたの「アイテム」オブジェクトは、二つのリストが同じアイテムを参照する理由です参照によって渡されます。

あなたがオブジェクト自体のクローンを作成する必要がありますが、メソッドreturnTheNewArrayList内のアイテムの新しいインスタンスを作成する必要がありますブランドの新しい参照(10の新しい参照のための10個の新しいインスタンス。)

public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item){ 
//create a new List 
ArrayList<Items> newList = new ArrayList<Items>(); 
int randomBin = r.nextInt(50); 
    for(Items oldItem:a){ 
     // make a copy of Item to get a new instance of Item for the new List 
     Item newItem = new Item(oldItem); 
     if(item==newItem.itemIds()){ 

      while(randomBin==newItem.bins()){ 
       randomBin = r.nextInt(50); 

      } 
      newItem.setBin(randomBin); 

     } 

     newList.add(newItem); 

    } 
return newList; 

} 
関連する問題