简体   繁体   中英

JAVA - Removing non iterator element from iterating list

I have a problem while going through this iterator loop, in which i go through each element of this.env, but within this list, wanting to remove a different element of said list. When I try to remove any item of said iterating list, I receive this error: , and as far as I understand this is caused due to modifying the iterating list without using iterator.remove(). ,据我所知,这是由于在不使用 iterator.remove() 的情况下修改迭代列表造成的。

Code:

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

Please have mercy with my coding skills, since I am only a beginner in java / Android, though any suggestions are greatly appreciated!

Thanks in advance!

If you are NOT using Iterator for whatever reason, you can collect the elements to be deleted in a Set when you are iterating over the collection, and after the loop you iterate over the Set and delete the elements from the original collection.

Note that this is only workable for small-sized collections.

HashSet toDelete = new HashSet();

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

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

Otherwise, you can just call remove() on the iterator.

I think it works now with adding a toDelete list, checking if the iterating item is already in the list, if it is, then skip it, and afterwards deleting it.

I haven't thoroughly checked for bugs, but for now it's fine. Working code:

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;

Thanks for the fast responses!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM