2016-03-30 212 views
2

我在通過此迭代器循環時遇到了一個問題,其中我遍歷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

如果因爲任何原因不使用迭代器,則可以在迭代集合時收集要刪除的元素,並在循環之後遍歷Set並從原始集合中刪除元素。

請注意,這隻適用於小尺寸的集合。

HashSet toDelete = new HashSet(); 

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

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

否則,你可以在迭代器上調用remove()。

+0

但是如果我不刪除每個循環後需要刪除的元素,它會再次觸發循環並執行操作即使它不應該存在? – TheFloppyToast

+0

他不應該這樣做,這是沒有意義的。如果他已經在使用迭代器,只需使用正確的功能 –

+0

@LucasCrawford如果不刪除迭代中剛剛訪問的元素,'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; 

感謝您的快速響應!