2016-09-21 10 views
1

イテレータを使用して反復されるブロックと呼ばれるArrayListがあります。現在のイテレータの.remove()メソッドを呼び出す前に、削除されるオブジェクトにリンクされているリスト内の別のオブジェクトを削除する必要があります。これを実行しようとすると、予期したとおりに同時変更例外が発生します。あなたは私がこれを回避する方法を知っていますか?サンプルコード:Javaは、同じリスト内の別の要素を削除するイテレータを削除します。

for (Iterator<Block> iterator = Blocks.iterator(); iterator.hasNext();) { 
    Block block = (Block) iterator.next(); 
    if (block.getX() == x && block.getY() == y) { 
     block.remove(); //This removes another block from this list but throws the error 
     iterator.remove(); 
    } 
} 
+0

最初のマッチ後にさらに要素を削除するにはイテレータが必要ですか?それとも最初の試合を取り除こうとしているだけですか? – Joffutt4

+0

ちょうど最初の試合、それは一度起こります。 – Funnythat

+1

基本的には、バグを見つけにくいイテレータを混乱させるので、その例外が発生します。したがって、イテレータでのみ行うか、ブロックを収集してループの後に削除してから削除する必要があります(たとえば、 'blocks.removeAll(blocksToRemove)'を使用して)。 - しかし、これはある種のゲームのように聞こえるので、デザインが合わないかもしれません。つまり、リンクされたブロックの代わりに、別の構造を使う方が良いかもしれません。 – Thomas

答えて

1

あなただけの最初のマッチを削除する必要がある場合は、最も簡単な解決策は、最初のマッチを見つけ、外でアクセスできる変数にその試合を節約するために、リストを反復処理するだろうイテレーターループ。その後、ループから抜け出し、必要なクリーンアップ(削除)を実行してください。

Block removeMe; 
for (Iterator<Block> iterator = Blocks.iterator(); iterator.hasNext();) { 
     Block block = (Block) iterator.next(); 
     if (block.getX() == x && block.getY() == y) { 
      removeMe = block; 
      iterator.remove(); 
      break; 
     } 
} 
removeMe.remove(); 
+0

これは私がトーマスのコメントから得たものであり、完璧に感謝しています! – Funnythat

関連する問題