2016-03-30 15 views
2

Bu yineleyici döngüsünden geçerken, this.env öğesinin her bir öğesinin içinden geçtiğimde bir sorunum var, ancak bu listede söz konusu listenin farklı bir öğesinin kaldırılmasını istiyorum. Söz konusu yinelenen listenin herhangi bir öğeyi kaldırmaya çalıştığımda, bu hatayı alıyorum: java.util.ConcurrentModificationException ve anladığım kadarıyla yineleme listesinin iterator.remove() kullanılmadan değiştirilmesinden kaynaklanıyor.JAVA - Yineleyici olmayan öğenin yinelenen listeden kaldırılması

Kodu: java/Android'de sadece bir acemi olduğum için herhangi bir öneri büyük takdir edilmektedir olsa

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!"); 
         } 
        } 
       } 

, benim kodlama becerileri ile merhamet edin!

Şimdiden teşekkürler!

+0

neden worldElementIterator.remove() 'ı denemediniz? –

+0

Yineleyicinin kendisini kaldırmaz mıydı? Listedeki özel bir öğeyi kaldırmak istiyorum ... – TheFloppyToast

+0

Hayır Sizin için aşağıda cevaplandırdım. En son erişilen öğeyi kaldırır, sizin durumunuzda worldElement koleksiyondan kaldırılır. Yineleyici kaldırılmaz, bu öğe. –

cevap

1

Herhangi bir nedenle yineleyici kullanmıyorsanız, koleksiyonun üzerinde yinelediğiniz sırada bir Set'e silinecek öğeleri toplayabilirsiniz ve döngüden sonra yineleyin ve bu sayede öğeleri orijinal koleksiyondan silebilirsiniz. .

Bunun yalnızca küçük boyutlu koleksiyonlar için kullanılabilir olduğunu unutmayın.

HashSet toDelete = new HashSet(); 

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

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

Aksi takdirde, yalnızca yineleyicideki remove() öğesini çağırabilirsiniz.

+0

Ama her döngüden sonra kaldırılması gereken öğeleri kaldırmazsam, döngü tekrar tetikler ve eylemleri yürütür Var olmasa bile mi? – TheFloppyToast

+0

Bunu yapmamalı, hiç mantıklı değil. Zaten bir yineleyici kullanıyorsa, yalnızca yineleme sırasında ziyaret edilen öğeyi kaldırmıyorsanız, –

+0

@LucasCrawford 'Iterator.remove()' işlevini kullanın. –

0

Şimdi bir toDelete listesi ekleyerek, yinelemeli öğenin listede olup olmadığını kontrol ediyor, eğer varsa, atla ve sonra siliyor.

Hatalar konusunda ayrıntılı bir kontrol gerçekleştirmedim, ancak şimdilik sorun yok. Çalışma kodu: hızlı yanıtlar için

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; 

teşekkürler!