今天在学习一个关于一个SurfaceView的时候,遇到了一个的异常,这个异常是怎么引发的呢,,,,如下两个对比的代码
先说一下需求,就是时刻便利已有的炸弹的位置,然后,如果超出了屏幕的范围,就会将这个炸弹对象移除数组,第一次我用的是for循环做的,什么毛病也没有。。
第一遍用for循环做的代码如下
for (int i = 0; i < booms.size(); i++) { booms.get(i).drawself(canvas); booms.get(i).move(); //判断炸弹是否移除屏幕呢 //拿到当前的屏幕的坐标点 if (booms.get(i).getPoint().x > getWidth() || booms.get(i).getPoint().x < 0 || booms.get(i).getPoint().y > getHeight() || booms.get(i).getPoint().y < 0) { booms.remove(i); } }
第二遍用了foreach的循环做了判断
for (Boom boom : booms) { boom.drawself(canvas); boom.move(); //判断炸弹是否移除屏幕呢 //拿到当前的屏幕的坐标点 if (boom.getPoint().x > getWidth() || boom.getPoint().x < 0 || boom.getPoint().y > getHeight() || boom.getPoint().y < 0) { booms.remove(boom); } }
这时候出现了错误如下:并发修改异常
06-14 08:19:48.852 4131-4278/com.lensman.myapplication E/AndroidRuntime: FATAL EXCEPTION: Thread-212
Process: com.lensman.myapplication, PID: 4131
java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com.lensman.myapplication.GameUI$override.drawUI(GameUI.java:94)
at com.lensman.myapplication.GameUI$override.static$access$100(GameUI.java:20)
at com.lensman.myapplication.GameUI$override.access$dispatch(GameUI.java)
at com.lensman.myapplication.GameUI.access$100(GameUI.java:0)
at com.lensman.myapplication.GameUI$RenderThread.run(GameUI.java:53)
当遍历集合的时候,修改集合元素会触发此异常
这是因为当我在遍历数据的同时,将集合里面的数据给删除了,,本来是10个数据,删除了之后变成了9个,,就会抛出异常
而上面的for循环为什么不发生呢?因为for是将size从新计算了一遍了,,,,而foreach是早就计算好了
怎么解决呢?备份一遍
系统给我们了一个类似的东西,,,
// private ArrayList<Boom> booms = new ArrayList<>(); private CopyOnWriteArrayList<Boom> booms= new CopyOnWriteArrayList<>();
将原来的ArrayList替换成为 CopyOnWriteArrayList这个就可以了