【扔物线】Android 高级开发瓶颈突破系列课-第五期
下崽ZY:51xuebc.com/thread-425-1-1.html
我要在for循环List中删除元素
仍然记得刚来第三天写个接口我就for循环内删除元素,当时很沙雕,恰恰又被代码走查看到了,为难的我挖了个洞将for改成了迭代器方式遍历,这两天看个大佬的代码,他就是for循环并remove其中元素,我开心的以为发现了一个bug,嗯,再往下看不对,这代码妙啊,百度了一下,有了这篇文章 下面我们经过几个例子以及剖析源码的方式来看看问题,nice
仍然记得刚来第三天写个接口我就for循环内删除元素,当时很沙雕,恰恰又被代码走查看到了,为难的我挖了个洞将for改成了迭代器方式遍历,这两天看个大佬的代码,他就是for循环并remove其中元素,我开心的以为发现了一个bug,嗯,再往下看不对,这代码妙啊,百度了一下,有了这篇文章 下面我们经过几个例子以及剖析源码的方式来看看问题,nice
我们按代码次第翻一下,索引在范围内,则获取remove的元素,然后将list的元素大小减一,假如还存在,就停止元素的copy,从源数组的index+1位置开端要复制的数组元素的数量numMoved,到目的数组的指定位置,然后经过GC将最后一个位置内存回收,哦。原来是这样的,至于说的报错我们下面在剖析
问题二
for (String ll : list) {
if(StrUtil.equals(ll,"333")){
list.remove(ll);
}}
复制代码
如上代码,当我们运用foreach的时分我们需求remove的是一个对象,而不是for时的下标,这里会报错java.util.ConcurrentModificationException,这就是我们说的**报错**了,我先把结果说了吧,这里我们删除元素的话其实并不会报错,报错的是for循环哪里,在你remove后下一次遍历的时分才会报错,报异常的办法是java.util.ArrayList$Itr.checkForComodification,一看就是办法里的迭代器报错,下面我们看看为啥???
我们先看这里的for循环在做啥
处理及躲避
好了,既然晓得问题的缘由了,那么我们该怎样躲避呢???
关于第一个问题,既然删除后它会前移,那我逆序遍历是不是就好了呢(逻辑鬼才),毕竟我for的size是动态变化的
for(int i = list.size()-1;i>=0;i--){
if(StrUtil.equals("222",list.get(i))){
String remove = list.remove(i);
System.out.println("shanchu"+ remove);
}}
复制代码
这个结果是啥;不用我说了吧**shanchu222 shanchu222 shanchu222 111 333 555,**你看圆满处理问题,这是一个处理方法,所以逆序的状况你不用太在意;
关于第二种状况
我们用迭代器看看
Iterator iterator = list.iterator();
while (iterator.hasNext()){
if(StrUtil.equals("222",iterator.next())){
list.remove(iterator.next());
}}