在使用hashMap的过程中遇到的一个问题,记录一下。
之前在做一个功能的时候,需要删除hashMap中的一些元素,当时最先想到的方案就是直接for循环,然后在循环中调用remove方法删除元素,如下所示;

HashMap<String,String> map = new HashMap();map.put("11","1");map.put("22","2");for (String key : map.keySet()) {if ("11".equals(key))map.remove(key);}

运行代码后就抛出如下异常:

后来在网上查了一些资料,并查看了一些源码。
原因是每次我们对hashmap进行修改操作时都会由一个modCount变量记录修改次数;
hashmap调用for循环的时候底层还是创建了一个迭代器
迭代器创建时会将 expectedModCount = modCount;

在上面报错代码中,我对hashmap进行了一次remove操作,modCount的值就会加1,比如说我们上面进行了两次put操作,modCount的值为2,再执行remove之后,modCount的值为3,但是在创建迭代器时,modCount将值赋给了expectedModCount,此时expectedModCount的值为2;

当下次循环时迭代器会去调用它的next()方法

next()方法中调用了nextNode()方法

此时会去校验modCount和expectedModCount的值是否相等,如果不相等就会抛出ConcurrentModificationException()异常。

解决方案:
要解决这个问题可以调用iterator迭代器的remove()方法。

  HashMap<String,String> map = new HashMap();map.put("11","1");map.put("22","2");
//        for (String key : map.keySet()) {//            if ("11".equals(key))
//                map.remove(key);
//        }Iterator<String> iterator = map.keySet().iterator();while (iterator.hasNext()) {String next = iterator.next();if ("11".equals(next)){iterator.remove();}

此时代码可以正常运行。
我们来看一下iterator的remove()方法;

在执行完删除操作后会再次将modCount的值赋值给expectedModCount。

以下是我的一些猜想:
因为hashmap是一个线程不安全的集合,为了防止在并发情况下,一个线程在循环时,另一个线程对hashMap集合进行修改操作而设计的。(fast-fail 快速失败的机制)。
所以这个异常叫ConcurrentModificationException()并发修改异常;

但是在单线程情况下,一些不恰当的操作也会触发这个异常。

记一次hashMap遍历时删除异常相关推荐

  1. HashMap遍历方法和实现原理分析

    1.HashMap 1.1.HashMap遍历方法 public class CircleMap { public static void main(String[] args) { //创建Hash ...

  2. Arraylist、HashSet去重复 treeSet排列实现方法 HashMap遍历取值

    2019独角兽企业重金招聘Python工程师标准>>> java提供的Arraylist本身不能对添加的元素进行去重,需要在添加后进行比较,如果相同就不添加 public stati ...

  3. Java HashMap 遍历方式性能探讨

    转载自 Java HashMap 遍历方式性能探讨 关于HashMap的实现这里就不展开了,具体可以参考JDK7与JDK8中HashMap的实现 JDK8之前,可以使用keySet或者entrySet ...

  4. hashmap中的key是有序的么_深入理解HashMap遍历元素的顺序

    HashMap遍历元素的顺序. 一,HashMap元素的底层存储顺序 我们都知道HashMap是"无序"的,也就是说不能保证插入顺序.但是,HashMap其实也是有序的,一组相同的 ...

  5. List如何在遍历时删除元素

    背景:业务中经常会涉及遍历list时对集合进行插入或者删除操作 一. 错误方式 先看看下面几段代码,1是foreach的方式去遍历list并删除元素,2是用迭代器的方式遍历list并删除元素,3是下标 ...

  6. List遍历时删除与迭代器(Iterator)解惑

    文章目录 ArrayList 遍历时删除方法 for循环向后遍历的陷阱 增强型for循环(foreach)遇到的问题 使用迭代器进行遍历同时修改操作 iterator调用remove()方法为什么要先 ...

  7. Java HashMap遍历实践

    在原始记忆中,Java HashMap遍历,无非是for each或者iterator,但至于在遍历时性能如何,优缺点如何,泛泛而不得知.对于这样的基础问题,对于王二(Java编程6年,幸好我的方向不 ...

  8. java map遍历顺序_深入理解HashMap遍历元素的顺序

    HashMap遍历元素的顺序. 一,HashMap元素的底层存储顺序 我们都知道HashMap是"无序"的,也就是说不能保证插入顺序.但是,HashMap其实也是有序的,一组相同的 ...

  9. HashMap遍历以及遍历顺序

    HashMap遍历以及遍历顺序 HashMap是Java语言中一种键值对(key-value)数据结构,但不记录key的插入顺序,如果要按照插入顺序进行遍历,则需要使用LinkedHashMap类型. ...

最新文章

  1. iOS 9音频应用播放音频之音量设置与声道设置
  2. Lync Server 2010的部署系列_第三章 证书、架构、DNS规划
  3. IOS开发UIScrollView控件详解
  4. 【剑指offer】面试题35:复杂链表的复制(Java)
  5. 上证50基金有哪些_定投基金(易方达上证50指数A)
  6. 怎么禁止浏览器自动保存密码?
  7. 我眼中的Web2.0
  8. [Done][DUBBO] dubbo Thread pool is EXHAUSTED!
  9. vs2010创建动态库(亲测可行)
  10. 【时间序列预测】基于matlab RBF神经网络时间序列预测【含Matlab源码 1336期】
  11. java遍历map集合传值,Java之五种遍历Map集合的方式
  12. tkinter教程_Tkinter教程–第2部分
  13. 演绎类清吧音响怎么选?
  14. php的include once,php include_once的使用方法详解
  15. 晶闸管整流桥matlab仿真,整流12脉中频电源MATLAB-Simulink仿真及谐波分析
  16. 如何成为一个更好的程序员,或者说是学习者?给你七个建议!
  17. 基于三相VSR的SVPWM调制
  18. 苏世民,我的经验和教训(一)
  19. 转:电容器的好坏测量
  20. MacBook Pro设置外接显示器竖屏显示,2k 字体小

热门文章

  1. maven连同所有依赖包一起打包成jar包
  2. 如何在Mac上将Heic图片快速转jpg或png?
  3. iphone投屏玩王者荣耀 无线连接投屏
  4. moto x android 6.0,New Moto X 2014版XT1085刷安卓6.0教程(转自爱黑武论坛)
  5. 关于PC与信捷PLC系列通信的问题
  6. 剑网3 最新服务器,《剑网3缘起》突然延期,疑似人气低迷撑不满服务器
  7. HTML5 离线缓存
  8. php ci 框架 扩展缓存类,PHP CodeIgniter框架的工作原理研究
  9. xstream 反序列化漏洞研究与修复
  10. 帆软10.0基于Mysql考勤模块开发