2012-03-16 59 views
0

在这个程序中删除元素我一直认为杀人最好的决斗决斗者的名单时,他们随机INT = 0 我有我的底部附近循环的麻烦和正在此错误:从一个ArrayList

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) 

代码

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); 


} 
} 
+3

请发布一个*更短*的示例,没有所有注释掉的行,没有大量带有多个空白行的区域,并带有正确的缩进。我敢肯定,你可以想出一个例子,它只需要很少的空间,它甚至不需要在SO中查看时滚动... – 2012-03-16 21:06:18

+0

[ArrayList的ConcurrentModificationException]的可能重复(http://stackoverflow.com/questions/3184883/concurrentmodificationexception-for-arraylist) – CoolBeans 2012-03-16 21:08:17

回答

3
for(Duelist element : duelers){ 

虽然你是这个块内,你遍历duelers列表,这意味着你不能没有造成改变列表除非您使用迭代器的remove()方法。

这里的问题是,你没有访问迭代器。所以你必须给你的foreach循环使用迭代器变成一个while循环:

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

(评论后更新) 或更好:

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

,而不是和

duelers.remove(element); 

编写

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

或者:您可以为迭代创建列表的副本。这是浪费内存(和代码味道),但如果你的应用程序很小,它应该没有什么区别,并且它将需要最少量的重写。

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

您应该对Iterator使用for循环来限制Iterator的范围。 – 2012-03-16 21:27:08

+0

@Steve true,但我讨厌'for(Iterator it = x.iterator(); it.hasNext();)'循环最后一段为空的地方。但是我认为这是更好的封装 – 2012-03-16 21:30:10

0

问题是此行duelers.remove(bestDueler);

你不应该在你遍历它来修改列表,而不是由for(Duelist element : duelers)
使用迭代器使用
您隐含使用迭代器迭代器明确地说即duelers.listIterator()并使用removeiterator而不是

1

您不能修改foreach循环中的集合,而是使用Itera如果您想删除某些内容,请使用Iterator.remove():