您的位置:首页 > 编程语言 > Java开发

[Crash分析] java.util.ConcurrentModificationException

2016-09-17 19:05 323 查看

【类型定位】

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


【个人总结】

java.util.ConcurrentModificationException 对应着迭代器失效的问题

迭代器失效问题,可以预先存一份临时容器,遍历这份临时容器,操作则在原来的容器中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息