简体   繁体   English

JAVA - 从迭代列表中删除非迭代器元素

[英]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.我在遍历这个迭代器循环时遇到了问题,我遍历 this.env 的每个元素,但在这个列表中,想要删除所述列表的不同元素。 When I try to remove any item of said iterating list, I receive this error: java.util.ConcurrentModificationException , and as far as I understand this is caused due to modifying the iterating list without using iterator.remove().当我尝试删除所述迭代列表的任何项目时,我收到此错误: java.util.ConcurrentModificationException ,据我所知,这是由于在不使用 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!请怜悯我的编码技巧,因为我只是 Java / Android 的初学者,尽管非常感谢任何建议!

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.如果出于某种原因不使用 Iterator,则可以在迭代集合时收集要在 Set 中删除的元素,并在循环之后迭代 Set 并从原始集合中删除元素。

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.否则,您只需在迭代器上调用 remove() 即可。

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.我认为它现在可以添加 toDelete 列表,检查迭代项是否已经在列表中,如果是,则跳过它,然后删除它。

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!感谢您的快速回复!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java-使用迭代器从链接列表中删除元素 - Java - Removing element from a Linked List using iterator 迭代时从列表中删除对象不起作用(使用迭代器) - Removing object from a list while iterating it doesn't work (with iterator) Java链接列表:使用迭代器删除最大的元素 - Java Linked List: Removing Largest Element Using Iterator ConcurrentModificationException 使用列表迭代器 java 删除元素时 - ConcurrentModificationException When removing element using list iterator java Java删除一个迭代器,该迭代器删除同一列表中的另一个元素 - Java removing an iterator that removes another element in the same list Java-使用for索引循环迭代列表时删除列表中的元素 - Java - removing an element in list while iterating it with a for index loop 为什么使用迭代器从列表中删除元素会导致ConcurrentModificationException? - Why removing element from list using iterator causes ConcurrentModificationException? 从Java中最里面的嵌套Iterator中删除元素会导致NoSuchElementException - Removing element from innermost nested Iterator in java causes NoSuchElementException ConcurrentModificationException从迭代器移除元素 - ConcurrentModificationException removing element from iterator Java List Iterator似乎未正确迭代 - Java List Iterator does not seem to be iterating properly
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM