2010-11-21 7 views
11

私は異なる動作を取得するのはなぜ:のJavaのaddAll(コレクション)新しいArrayListを(コレクション)対

  1. Collection col2 = new ArrayList(col);

  2. Collection col2 = new ArrayList();
    col2.addAll(col)

私が働いています視聴者と、コードが複雑で、私は問題の "根"を説明しようとしている。もう一つの興味深い事実は、次のいずれかです...

//IF i use this code i have the correct behavior in my app: 
public void updateCollection(Collection<Object> col) { 
    this.objectCollection.clear(); 
    this.objectCollection.addAll(col); 
} 

//IF i use this code i have unexpected behavior in my app: 
public void updateCollection(Collection<Object> col) { 
    this.objectCollection=new ArrayList(col); 
} 
+7

正確な動作がわかりにくいですか? –

+0

私のコードは、a)またはb)を使用して異なる動作をしています。私の考えでは、どちらの操作も同じ結果につながりますが、明らかにそうではありません。何かが違う。 – marcolopes

+2

あなたはまだあまりにも曖昧です。何が起こるのですか?何が起こらない?ご使用の環境で期待される結果と一緒に[SSCCE](http://sscce.org)を投稿してください。 – BalusC

答えて

14

このコードは動作します

public void updateCollection(Collection<Object> col) { 
    this.objectCollection=new ArrayList(col); 
} 

私はあなたの最初の方法でこの変化は、同一の問題導入することを疑う:

public void updateCollection(Collection<Object> col) { 
    this.objectCollection = new ArrayList(); 
    this.objectCollection.clear(); 
    this.objectCollection.addAll(col); 
} 

はなぜ?明らかに、あなたはどこかで使用されているobjectCollectionへの別の参照を持っています。あなたのコードのどこかで、別のオブジェクトが言っている(例えば):

myCopyOfObjectCollection = theOtherObject.objectCollection;

ゲッターを使用している場合でも、基本的な動作は変わりません。あなたはまだ別のリファレンスを保持しています。だから、

初期割り当ての場合、たとえば、含まれているコレクション{1、2、3}、あなたがして起動します。

  • this.objectCollection:{1、2、3}
  • います。copyOfObjectCollection:{1、2、3}

あなたはthis.objectCollectionへ新しいのArrayListを割り当て、そして、たとえば、を移入 {4、5、6}、あなたはこれを取得:

  • this.objectCollection:{4,5,6}
  • that.copyOfObjectCollection:{1、2、3}

"その"は依然として元のArrayListを指しています。

5
Collection col2 = new ArrayList(col); 

はサイズcol.size()(+ 10%)と新しいArrayListを作成し、その配列にcolからすべての要素をコピーします。

Collection col2 = new ArrayList(); 

は、(少なくとも、Sunの実装で)10の初期サイズで新しいのArrayListを作成します。

col2.addAll(col); 

は、必要に応じて、補助配列のサイズを大きく、col2ArrayListの終わりにcolからすべての要素をコピーします。

したがって、colのコレクションサイズに応じて、動作は少し異なりますが、あまり大きくはありません。少なくとも一つの追加の補助配列の拡張操作を避けることができます -

最初のオプションを使用することが好ましいです。

public void updateCollection(Collection<Object> col) { 
    this.objectCollection.clear(); 
    this.objectCollection.addAll(col); 
} 

をしかし、これは問題が導入されています:

+0

最初のアプローチを使用して私のコードは動作しません... – marcolopes

0

私は、簡単に美しいと思う、ちょうど発電機セッター/ゲッター方法は良い習慣です。 最初にクリアしてからaddAllを実行すると、リストのすべての要素をクリアする必要があります。その後、addAllは余分な配列拡張操作になります。これは科学ではありません。

ちょうど置換、この変数は新しいリストを指します、古いリストは自動GCになります。

関連する問題