2011-12-07 3 views
1

私は、レストランオブジェクトを格納するarraylistを繰り返し処理しようとしていますが、ループは5つの要素のうち3つしか通過しないという問題があります。ループ全体がループしていない

私が説明するための試験方法作成:テストはそれに5つの食堂オブジェクトを持つことになります。ここ

public void testLoop() { 
     ArrayList<Eatery> test = new ArrayList<Eatery>(); 
     test = eateriesListDefault; 
     for(Eatery e : test) { 
      MyLog.e(TAG, "Name: " + e.getName()); 
     } 
     for (int i = 0; i < eateriesListDefault.size(); i++) { 
      MyLog.e(TAG, "Name " + test.get(i).getName()); 
      test.remove(i); 
     } 
     for(Eatery e : test) { 
      MyLog.e(TAG, "Name " + e.getName()); 
     } 
    } 

を。最初のループは5つの名前のうち5つを正常に表示します。 2番目のループは3つの飲食店を削除するだけなので、最後のループは2つの名前を表示します。

私は、しかし私は、同時アクセスのエラーを取得し、第二のループの代わりに

for(Eatery e : eateriesListDefault) { 
      MyLog.e(TAG, "Name: " + e.getName()); 
      test.remove(e); 
} 

を使用して試してみました。

誰かが私が間違っていることを知っていますか?

+2

まず第一に、あなたはいけませんコレクションから値を削除しようとするときに 'foreach'ループを使います。これが同時アクセスエラーの原因です。 [このページ](http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html)を参照してください。次の行に代入を作成するためだけに 'new ArrayList'コールを発行する理由についても説明できますか? – Grambot

+0

eateriesListDefaultはどのように見えますか?おそらく、最初のループとして「for(Eatery e:test)」の代わりに、2回目のループを模倣してみて、リンゴとリンゴを比較することができます。インデックス作成の問題を排除しようとしています。 – dispake

答えて

7

あなたはそれぞれのループの繰り返しでeateriesListDefault.size()を呼び出しています。同時に、あなたはtest.remove(i)と呼んでいます。これは、繰り返しごとに1つずつ配列を短絡しています。あなたのループは、本質的にこれをやっている:

  1. I = 0 サイズ= 5

  2. を継続して行っていきI = 1つの サイズ= 4

  3. 私は= 2 サイズを予定してください= 3 続ける

  4. i = 3 サイズ= 2 停止

あなたの目標は、それを削除し、配列の最初の要素をプリントアウトした場合は、おそらくこのループによってそこに得ることができますが:

while(!eateriesListDefault.isEmpty()) { 
    MyLog.e(TAG, "Name " + test.get(0).getName()); 
    test.remove(0); 
} 
+0

+1すてきなイラスト。タイプミスを修正しました。 –

2

ループインデックスが増加し続けている間、2番目のループは配列から要素を削除します。 4番目のパスでは、ループインデックスは3ですが、eateriesListDefault.sizeは2であるため、ループは終了します。

は、代わりにこれを試してみてください:

for (Iterator<Eatery> it = test.iterator(); it.hasNext();) { 
    MyLog.e(...) 
    it.remove(); 
} 

リスト()Iterator.removeを呼び出すこと以外の方法で反復中に変更された場合、反復子の動作は不定です。 Iterator.remove() documentationを参照してください。

また、デフォルトリストのコピーを作成することもできます。あなたの "test ="ステートメントは、同じリストへの新しい参照を作成するだけです。

test = new ArrayList<Eatery>(eateriesListDefault); 
+1

拡張の説明:ループがどのように動作するかを考えた場合、複数のステップが得られます。ステップ1、リストサイズ= 5、要素を削除します。ステップ2、リストサイズ= 4、要素を削除する。ステップ3、ループサイズ= 3、終了。 – Grambot

関連する問題