前言:
遍历集合根据某个条件对集合内容进行增加或者删除,但是前几天使用增强for循环遍历集合并把集合中的某些元素删除的时候会抛出异常:ConcurrentModificationException
如图所示
解决方法:
把增强for循环改成普通for循环,按索引取出对象
下面两段代码均为调用了hitTank方法,hitTank方法里有remove方法,会实时改变enemyTank集合的元素
public void hitTank(Shot shot,EnemyTank enemyTank){
//判断子弹的横纵坐标是否和敌方坦克重合
if(shot.x > enemyTank.getX() && shot.x < enemyTank.getX() + 80
&& shot.y > enemyTank.getY() && shot.y < enemyTank.getY() + 80){
shot.isLive = false;
enemyTank.setLive(false);
//remove删除集合元素的方法在这里
enemyTanks.remove(enemyTank);
//生命设置false后,new一个Bomb加入到Bombs中
bombs.add(new Bomb(enemyTank.getX(), enemyTank.getY()));
}
}
未修改前
if(hero.shot != null && hero.shot.isLive){
for (EnemyTank enemyTank : enemyTanks) {
hitTank(hero.shot,enemyTank);
}
}
修改后
if(hero.shot != null && hero.shot.isLive){
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
hitTank(hero.shot,enemyTank);
}
}
异常原因:
ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
原因:ArraayList迭代器有个Itr,其内部有个属性expectedModCount。而集合有个fail-fast快速失败检测机制,当进行remove()操作时,会比对expectedModCount是否与modCount相等,而前者一般不会改变,但remove操作会导致modCount发生改变。一旦两者不等,就会抛出此异常