在软件构造实验Lab2的ConcreteVerticesGraph里,需要我们编写remove()方法。移除一个点没有别的方法,只有遍历集合vertices(),找到该点并移除。

当时我没有写上红框中的break,出现了ConcurrentModificationException的报错。写实验时没有仔细深究,上网搜索也没有看明白,写出break也是机缘巧合下想到了,后来搜索资料,详细地了解了一下这个报错。

异常简介

ConcurrentModificationException是基于java集合中的 快速失败(fail-fast) 机制产生的,在使用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了增删改,就会抛出该异常。
快速失败机制使得java的集合类不能在多线程下并发修改,也不能在迭代过程中被修改。

抛出异常的原因

在实验中,我们使用ArrayList的remove方法遍历并移除元素。

此时会抛出异常:
Exception in thread “main” java.util.ConcurrentModificationException

参考ArrayList的源码中关于remove的片段

 1 public void remove() {
2 if (lastRet < 0)
3 throw new IllegalStateException();
4 checkForComodification();
5
6 try {
7 ArrayList.this.remove(lastRet);
8 cursor = lastRet;
9 lastRet = -1;
10 expectedModCount = modCount;
11 } catch (IndexOutOfBoundsException ex) {
12 throw new ConcurrentModificationException();
13 }
14 }
15 final void checkForComodification() {
16 if (modCount != expectedModCount)
17 throw new ConcurrentModificationException();
18 }

remove会检测是否有修改,判断依据为modCount != expectedModCount,每当变更列表,都会改变modCount的值,如果检测到modCount != expectedModCount,那么就会抛出Concurrent Modification Exception。
foreach循环遍历集合,实际上隐式调用了迭代器遍历,同样调用集合的remove或add等方法会抛异常;

解决方案

1.使用Iterator提供的remove方法,用于删除当前元素。

2.新建一个集合存放要删除的元素,之后统一删除。

3.不使用iterator遍历,但是这里要注意移除了一个元素,索引i也随之改变。

参考博客:

https://blog.csdn.net/weixin_40807247/article/details/88413347?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1-88413347-blog-79559814.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-1-88413347-blog-79559814.pc_relevant_default&utm_relevant_index=2

https://blog.csdn.net/leeafay/article/details/79559814?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79559814-blog-81485867.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-79559814-blog-81485867.pc_relevant_paycolumn_v3&utm_relevant_index=1

最新文章

  1. 绘制扇形效果线条小Bug解决
  2. C++ 生成 dll 和调用 dll 的方法实例(转)
  3. 定时备份mysql
  4. BZOJ-1477 青蛙的约会 拓展欧几里德
  5. Android SDK无法更新解决方法
  6. JedisPool连接池实现难点
  7. cdev_系列函数
  8. Cannot generate SSPI context---MS SQL ERROR
  9. 组件局域网中的无集线器、Windows XP、Windows 7、Windows 8的对等网
  10. 《JS权威指南学习总结--1.1语言核心》
  11. yum 安装Apache
  12. Android Gradle Task
  13. Idea快捷键和使用技巧【未完】
  14. Java基础实训2
  15. Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)
  16. Spark记录-官网学习配置篇(二)
  17. mongoose实现批量删除和多id查询的api/方法
  18. Confluence 6 LDAP 连接池配置参数
  19. 【渗透测试学习平台】 web for pentester -4.目录遍历
  20. Cat VS Dog---hdu3829(最大独立集)

热门文章

  1. vue修改内容点击显示隐藏内容不自动刷新问题
  2. Java 进阶P-4.8+P-4.9
  3. Quartz帮助类
  4. Feign远程调用 (介绍与使用)
  5. bind使用场景之一
  6. MRS+LakeFormation:打造一站式湖仓,释放数据价值
  7. P3804 【模板】后缀自动机 (SAM) &amp;&amp; P6139 【模板】广义后缀自动机(广义 SAM)
  8. reids(2)概述与安装
  9. Linux:atime、mtime、ctime
  10. C语言数据结构串的表示与操作的实现