[Crash分析] java.util.ConcurrentModificationException

来源:互联网 发布:mac怎么免费下载软件 编辑:程序博客网 时间:2024/06/14 20:35

【类型定位】

  java.util.ConcurrentModificationException这种类型的crash我们在使用容器的迭代器的时候可能会遇到,它对应了迭代器失效这一类型的crash。这种crash的成因是在遍历容器的过程中,动态更改了容器中的内容大小(增加或者删除),这样引起了迭代器失效的问题。
  

【解决方案】

迭代器失效的问题,解决的方案比较简单:先拷贝一份临时容器存放原来容器中的内容,再对这份临时的容器进行遍历操作,这样即使在遍历操作过程中会有对容器内容有增删的操作,也可以将这部分增删操作作用于原来的容器,而不影响现在正在遍历的容器。

【代码展示】

首先是会引起java.util.ConcurrentModificationException的crash:

public class MainActivity extends AppCompatActivity {    List<String> datas = new ArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        for (int i = 0; i < 10; ++i) {            datas.add(i, "item" + i);        }        for (String str : datas) {            removeOneDataItem(str);            //addOneDataItem(str);        }    }    void removeOneDataItem(String str) {        datas.remove(str);    }    void addOneDataItem(String str) {        datas.add(datas.size(), str);    }}

下面同时定义临时容器存放原来容器中的对象,遍历新的临时容器,再操作原来的容器:

public class MainActivity extends AppCompatActivity {    List<String> datas = new ArrayList<>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        for (int i = 0; i < 10; ++i) {            datas.add(i, "item" + i);        }        /**         * 关键是这一步:将原来需要遍历的容器拷贝一份临时         *      后续遍历操作在这份容器中         *      增删操作在原来的容器中         */        List<String> tempDatas = new ArrayList<>(datas);        for (String str : tempDatas) {            removeOneDataItem(str);            //addOneDataItem(str);        }    }    void removeOneDataItem(String str) {        datas.remove(str);    }    void addOneDataItem(String str) {        datas.add(datas.size(), str);    }}

【个人总结】

  1. java.util.ConcurrentModificationException 对应着迭代器失效的问题
  2. 迭代器失效问题,可以预先存一份临时容器,遍历这份临时容器,操作则在原来的容器中
0 0
原创粉丝点击