-
Notifications
You must be signed in to change notification settings - Fork 45
foreach remove concurrentmodificationexception
landon edited this page Jun 25, 2018
·
1 revision
- 并非foreach-remove一定抛出ConcurrentModificationException
- 主要看hasNext和next方法(cursor和size是关键),比如是删除倒数第二个元素的时候,cursor和size正好相等,遍历结束则成功给删除倒数第二个元素
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
for (String str : list) {
if ("1".equals(str)) {
list.remove(str);
}
}
- 这个业务逻辑正常,不会抛出异常
- ArrayList#Itr#hasNext return cursor != size
- cursor = 0;size = 2;
- ArrayList#Itr#next checkForComodification 此时modCount == expectedModCount == 2;cursor = i + 1;cursor = 1;
- if ("1".equals(str) == true
- ArrayList#remove(Object o)#fastRemove#modCount++,modCount变为3,--size,size变为1
- 继续hasNext,cursor = 1,size = 1,跳出,结束
List<String> list2 = new ArrayList<>();
list2.add("1");
list2.add("2");
for (String str : list) {
if ("2".equals(str)) {
list2.remove(str);
}
}
- 这个却抛出了java.util.ConcurrentModificationException,为什么二者结果不同呢?
- ArrayList#Itr#hasNext return cursor != size
- cursor = 0;size = 2
- ArrayList#Itr#next checkForComodification 此时modCount == expectedModCount == 2;cursor = i + 1;cursor = 1;
- 继续hasNext/next,cursor = 2
- ArrayList#remove(Objecto)#fastRemove#modCount++,modCount变为3,--size,size变为1
- 继续hasNext,cursor = 2,size = 1,cursor!=size,继续next,此时checkForComodification,则modCount=3,而expectedModCount =2,则抛出异常