2016-03-30 17 views
2

このiteratorループを実行中に問題が発生します。このiteratorループでは、this.envの各要素を調べますが、このリスト内では、そのリストの別の要素を削除します。上記の反復リストの項目を削除しようとすると、私はこのエラーを受け取ります:java.util.ConcurrentModificationExceptionこれは、iterator.remove()を使用せずに反復リストを変更したことが原因であると理解しています。JAVA - 反復リストから非イテレータ要素を削除する

コード:

public void envActions(IOHandler ioHandler, PlayerClass player){ 
    Iterator<WorldElement> worldElementIterator = this.env.iterator(); 
    while(worldElementIterator.hasNext()){ 
     WorldElement worldElement = worldElementIterator.next(); 
    //for(WorldElement worldElement:this.env){ 
     if(worldElement instanceof EntityClass){ 
      EntityClass entity=(EntityClass) worldElement; 
      if(entity.nature.contains("hostile")){ 
       MonsterClass mEntity=(MonsterClass) entity; 
       if(!(mEntity.attacks.size()*(Math.random()+0.25)>=mEntity.attacks.size())){ 
        Double followerNum = (Math.random()*player.followers.size()); 
        Integer followerNumInt=followerNum.intValue(); 
        if(followerNumInt<2){ 
         PlayerClass target=player; 
         Double attacknumD=mEntity.attacks.size()*Math.random(); 
         Integer attacknum= attacknumD.intValue(); 
         Integer playerarmor=player.getArmorValue(); 
         int enemydamage=mEntity.attacks.get(attacknum).getDamage()*(1-(playerarmor/1000)); 
         target.health=target.health-enemydamage; 
         ioHandler.printToConsole("\nThe "+mEntity.name+" attacked you with "+mEntity.attacks.get(attacknum).getAttack()+" and did "+mEntity.attacks.get(attacknum).getDamage()+" damage! you have "+player.health+" health left!"); 
        } else { 
         FriendlyCreatureClass target=player.followers.get(followerNumInt); 
         Double attacknumD=mEntity.attacks.size()*Math.random(); 
         Integer attacknum= attacknumD.intValue(); 
         int enemydamage=mEntity.attacks.get(attacknum).getDamage(); 
         target.health=target.health-enemydamage; 
         if(!target.isAlive()){ 
          ioHandler.printToConsole("\nThe " + mEntity.name + " attacked " + target.name + " with " + mEntity.attacks.get(attacknum).getAttack() + " and did " + mEntity.attacks.get(attacknum).getDamage() + " damage! " + target.name+" died! Farewell "+target.name+"."); 
          target.died(ioHandler, this, player, true); 
          //>>>> THIS IS WHERE I WOUlD LIKE TO REMOVE 'target' FROM THE env LIST <<<< 
         } else { 
          ioHandler.printToConsole("\nThe "+mEntity.name+" attacked "+target.name+" with "+mEntity.attacks.get(attacknum).getAttack()+" and did "+mEntity.attacks.get(attacknum).getDamage()+" damage! "+target.name+" has "+target.health+" health left!"); 
         } 
        } 
       } 

任意の提案は大歓迎しているが、私は、唯一のJava/Androidので初心者ですから、自分のコーディングスキルを持つ慈悲を持っていてください!

ありがとうございます!

+0

worldElementIterator.remove()を試してみませんか? –

+0

イテレータ自体は削除されませんか?リスト内のカスタム要素を削除したいのですが... – TheFloppyToast

+0

いいえ、私はあなたのために以下に答えました。あなたのケースでは、worldElementがコレクションから削除されます。イテレータは削除されず、要素です。 –

答えて

1

Iteratorを何らかの理由で使用していない場合は、コレクションを反復処理するときにSetで削除する要素を収集し、ループの後でSetを反復処理して要素を元のコレクションから削除できます。

これは、小規模なコレクションでのみ有効です。

HashSet toDelete = new HashSet(); 

for (...) { 
    if (...) 
     toDelete.add(item); 
} 
// end for 

foreach (item in toDelete) { 
    // delete from original collection 
} 

それ以外の場合は、イテレータでremove()を呼び出すことができます。

+0

しかし、私はすべてのループラウンド後に削除する必要がある要素を削除しないと、ループを再度トリガしてアクションを実行しますたとえそれが存在すべきではないとしても? – TheFloppyToast

+0

彼はこれをしてはならない、それは意味をなさない。彼が既にIteratorを使用している場合は、正しい機能を利用してください。 –

+0

@ iterator.remove()は、反復で今訪問された要素を削除しない場合は機能しません。 –

0

これは、toDeleteリストを追加して、反復アイテムが既にリストにあるかどうかをチェックしている場合はそれをスキップし、その後削除することで動作すると思います。

私はバグを完全にチェックしていませんが、今のところは問題ありません。 ワーキングコード:高速な応答のための

public void envActions(IOHandler ioHandler, PlayerClass player){ 
    List<WorldElement> toDelete=new ArrayList<>(); 
    Iterator<WorldElement> worldElementIterator = this.env.iterator(); 
    while(worldElementIterator.hasNext()){ 
     WorldElement worldElement = worldElementIterator.next(); 
    //for(WorldElement worldElement:this.env){ 
     if(worldElement instanceof EntityClass && !toDelete.contains(worldElement)){ 
      EntityClass entity=(EntityClass) worldElement; 
      if(entity.nature.contains("hostile")){ 
       MonsterClass mEntity=(MonsterClass) entity; 
       if(!(mEntity.attacks.size()*(Math.random()+0.25)>=mEntity.attacks.size())){ 
        Double followerNum = (Math.random()*player.followers.size()); 
        Integer followerNumInt=followerNum.intValue(); 
        if(followerNumInt<2){ 
         PlayerClass target=player; 
         Double attacknumD=mEntity.attacks.size()*Math.random(); 
         Integer attacknum= attacknumD.intValue(); 
         Integer playerarmor=player.getArmorValue(); 
         int enemydamage=mEntity.attacks.get(attacknum).getDamage()*(1-(playerarmor/1000)); 
         target.health=target.health-enemydamage; 
         ioHandler.printToConsole("\nThe "+mEntity.name+" attacked you with "+mEntity.attacks.get(attacknum).getAttack()+" and did "+mEntity.attacks.get(attacknum).getDamage()+" damage! you have "+player.health+" health left!"); 
        } else { 
         FriendlyCreatureClass target=player.followers.get(followerNumInt); 
         Double attacknumD=mEntity.attacks.size()*Math.random(); 
         Integer attacknum= attacknumD.intValue(); 
         int enemydamage=mEntity.attacks.get(attacknum).getDamage(); 
         target.health=target.health-enemydamage; 
         if(!target.isAlive()){ 
          ioHandler.printToConsole("\nThe " + mEntity.name + " attacked " + target.name + " with " + mEntity.attacks.get(attacknum).getAttack() + " and did " + mEntity.attacks.get(attacknum).getDamage() + " damage! " + target.name + " died! Farewell " + target.name + "."); 
          target.died(ioHandler, this, player, false); 
          toDelete.add(target); 
         } else { 
          ioHandler.printToConsole("\nThe "+mEntity.name+" attacked "+target.name+" with "+mEntity.attacks.get(attacknum).getAttack()+" and did "+mEntity.attacks.get(attacknum).getDamage()+" damage! "+target.name+" has "+target.health+" health left!"); 
         } 
        } 
       } 
    for(WorldElement worldElement:toDelete){ 
     this.env.remove(worldElement); 
    } 
    return; 

ありがとう!

関連する問題