简体   繁体   English

从ArrayList中删除元素

[英]Removing elements from an ArrayList

In this program I keep a list of duelists that kill the best duelist when their random int = 0. I am having trouble with my loop near the bottom and am getting this error: 在此程序中,我保留了一个清单清单,这些清单在其随机int = 0时会杀死最佳清单清单。

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at Duelist.main(Duelist.java:74)

Code

import java.util.Arrays;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collections;

public class Duelist implements Comparable{

private String name;
private int chance;
private boolean alive;


public Duelist(String duelistName, int hitChance){
    alive = true;
    name = duelistName;
    chance = hitChance;

    }
public String getName(){
    return name;
}
public int getChance(){
    return chance;
}
public boolean getLife(){
    return alive;
}
public void kill(){
    alive = false;
}

 public int compareTo(Object anotherDuelist) throws ClassCastException {
        if (!(anotherDuelist instanceof Duelist))
          throw new ClassCastException("A Duelist object expected.");
        int anotherDuelistChance = ((Duelist) anotherDuelist).getChance();  
        return this.chance - anotherDuelistChance;    
      }

public static void main(String[] args){

ArrayList<Duelist> duelers = new ArrayList<Duelist>(5);
//ArrayList<Duelist> personToKill= new ArrayList<Duelist>(5);
ArrayList<Duelist> rank = new ArrayList<Duelist>(5);
Random generator = new Random();




Duelist Antoine = new Duelist("Antoine", 3);
Duelist Francis = new Duelist("Francis", 6);
Duelist Juliette = new Duelist("Juliettee", 1);

duelers.add(Antoine); duelers.add(Francis); duelers.add(Juliette);



//System.out.println(duelers);


//for(Duelist element : duelers){
//  System.out.println(element.getName());
//  System.out.println(element.getChance());
//}
Collections.sort(duelers);
Collections.reverse(duelers);
//for(Duelist element : duelers){
    //System.out.println(element.getName());
    //System.out.println(element.getChance());
//}

while(duelers.size() > 1){


    for(Duelist element : duelers){



            System.out.println(element.getName());
            System.out.println("Chance:" + element.getChance());
            int randomInt = generator.nextInt(element.getChance());
            System.out.println("Random int " + randomInt);



            //Destroy target if randomInt equals 0
            if (randomInt == 0){


                //Check to make sure the best duelist is not killing themselves
                if (element.equals(duelers.get(duelers.size()-1))){
                    System.out.println("LASTDUDE");
                    Duelist bestDueler = duelers.get(duelers.size()-2);
                    bestDueler.kill();
                    rank.add(element);
                    duelers.remove(bestDueler);
                }

                else {
                    System.out.println("Killshot");
                    Duelist bestDueler = duelers.get(duelers.size()-1);
                    bestDueler.kill();
                    rank.add(element);
                    duelers.remove(bestDueler);
                }

            }


    }
}
System.out.println(duelers);


}
}
for(Duelist element : duelers){

While you are inside this block, you are iterating over the duelers list, which means that you can't change the list without causing a ConcurrentModificationException unless you use the iterator's remove() method. 在此块中时,您正在遍历决斗者列表,这意味着除非使用迭代器的remove()方法,否则在不引起ConcurrentModificationException情况下就不能更改列表。

The problem here is, you don't have access to the iterator. 这里的问题是,您无权访问迭代器。 So you'll have to change your foreach loop to a while loop with an iterator: 因此,您必须使用迭代器将foreach循环更改为while循环:

Iterator<Duelist> it = duelists.iterator();
while(it.hasNext()){
    Duelist element = it.next();
    // continue as before

(update after comments) or better: (评论后更新)或更好:

for(Iterator<X> it=x.iterator();it.hasNext();){
    Duelist element = it.next();
    //continue as before

and instead of 而不是

duelers.remove(element);

write

// the problem here is: you can only remove the current element,
// so you'll have to re-think some of your code
it.remove();

Or: you could create a copy of your list for iterating. 或者:您可以创建列表的副本以进行迭代。 That's a waste of memory (and a code smell) but if your application is small it should not make much of a difference, and it would require the least amount of rewriting on your part. 那是浪费内存(和代码异味),但是如果您的应用程序很小,那么它就不会有太大的改变,并且这将需要最少的重写。

for(Duelist element : new ArrayList<Duelist>(duelers)){
// continue as above

您不能在foreach循环中修改集合,而要使用Iterator,并且要删除某些内容时,请使用Iterator.remove():

The problem is this line duelers.remove(bestDueler); 问题是此行duelers.remove(bestDueler);

You are not supposed to modify the list while you iterate over it and not use the iterator 在迭代列表且不使用迭代器时,不应修改列表
You are implicitely using an iterator by for(Duelist element : duelers) 您隐式地使用for(Duelist element : duelers)的迭代器
Use an iterator explicitily ie duelers.listIterator() and use the remove of iterator instead 明确地使用迭代器,即duelers.listIterator()而使用remove iterator

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

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