电子商务网站开发意义,计算机培训班出来好找工作吗,广州市企业网站建设企业,中国建设银行龙卡信用卡网站2019独角兽企业重金招聘Python工程师标准 如果你是一名Java开发人员#xff0c;我能够确定你肯定知道ConcurrentModificationException#xff0c;它是在使用迭代器遍历集合对象时修改集合对象造成的#xff08;并发修改#xff09;异常。实际上#xff0c;… 2019独角兽企业重金招聘Python工程师标准 如果你是一名Java开发人员我能够确定你肯定知道ConcurrentModificationException它是在使用迭代器遍历集合对象时修改集合对象造成的并发修改异常。实际上Java的集合框架是迭代器设计模式的一个很好的实现。 Java 1.5引入了java.util.concurrent包其中Collection类的实现允许在运行过程中修改集合对象。 ConcurrentHashMap是一个与HashMap很相似的类但是它支持在运行时修改集合对象。 让我们通过一个简单的程序来帮助理解 ConcurrentHashMapExample.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 packagecom.journaldev.util; importjava.util.HashMap; importjava.util.Iterator; importjava.util.Map; importjava.util.concurrent.ConcurrentHashMap; publicclassConcurrentHashMapExample { publicstaticvoidmain(String[] args) { //ConcurrentHashMap MapString,String myMap newConcurrentHashMapString,String(); myMap.put(1,1); myMap.put(2,1); myMap.put(3,1); myMap.put(4,1); myMap.put(5,1); myMap.put(6,1); System.out.println(ConcurrentHashMap before iterator: myMap); IteratorString it myMap.keySet().iterator(); while(it.hasNext()){ String key it.next(); if(key.equals(3)) myMap.put(keynew,new3); } System.out.println(ConcurrentHashMap after iterator: myMap); //HashMap myMap newHashMapString,String(); myMap.put(1,1); myMap.put(2,1); myMap.put(3,1); myMap.put(4,1); myMap.put(5,1); myMap.put(6,1); System.out.println(HashMap before iterator: myMap); IteratorString it1 myMap.keySet().iterator(); while(it1.hasNext()){ String key it1.next(); if(key.equals(3)) myMap.put(keynew,new3); } System.out.println(HashMap after iterator: myMap); } } 当我们试着运行上面的程序输出如下 1 2 3 4 5 6 7 ConcurrentHashMap before iterator: {11, 51, 61, 31, 41, 21} ConcurrentHashMap after iterator: {11, 3newnew3, 51, 61, 31, 41, 21} HashMap before iterator: {31, 21, 11, 61, 51, 41} Exceptioninthreadmainjava.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) at java.util.HashMap$KeyIterator.next(HashMap.java:828) at com.test.ConcurrentHashMapExample.main(ConcurrentHashMapExample.java:44) 查看输出很明显ConcurrentHashMap可以支持向map中添加新元素而HashMap则抛出了ConcurrentModificationException。 查看异常堆栈记录可以发现是下面这条语句抛出异常 1 String key it1.next(); 这就意味着新的元素在HashMap中已经插入了但是在迭代器执行时出现错误。事实上集合对象的迭代器提供快速失败Fail-Fast的机制即修改集合对象结构或者元素数量都会使迭代器触发这个异常。 但是迭代器是怎么知道HashMap被修改了呢我们可以一次取出HashMap的所有Key然后进行遍历。 HashMap包含一个修改计数器当你调用它的next()方法来获取下一个元素时迭代器将会用到这个计数器。 HashMap.java 1 2 3 4 5 6 7 /** * HashMap结构的修改次数 * 结构修改是指改变了HashMap中mapping的个数或者其中的内部结构比如重新计算hash值 * 这个字段在通过Collection操作Hashmap时提供快速失败Fail-fast功能。 * 参见 ConcurrentModificationException。 */ transientvolatileintmodCount; 现在为了证明上面的观点我们对原来的代码做一点修改使迭代器在插入新的元素后跳出循环。只要在调用put方法后增加一个break 1 2 3 4 if(key.equals(3)){ myMap.put(keynew,new3); break; } 再执行修改后的代码会得到下面的输出结果 1 2 3 4 ConcurrentHashMap before iterator: {11, 51, 61, 31, 41, 21} ConcurrentHashMap after iterator: {11, 3newnew3, 51, 61, 31, 41, 21} HashMap before iterator: {31, 21, 11, 61, 51, 41} HashMap after iterator: {31, 21, 11, 3newnew3, 61, 51, 41} 最后如果我们不添加新的元素而是修改已经存在的键值对会不会抛出异常呢 修改原来的程序并且自己验证一下 1 2 //myMap.put(keynew, new3); myMap.put(key,new3); 如果你对于输出结果感觉困惑或者震惊在下面评论。我会很乐意给出进一步解释。 你有没有注意到那些我们在创建集合和迭代器时的尖括号在Java中这叫做泛型当涉及到编译时的类型检查和去除运行时的ClassCastException的时候会很有帮助。点击这里可以了解更多泛型教程。 原文链接 journaldev 翻译 ImportNew.com - 风恋星 译文链接 http://www.importnew.com/8162.html [ 转载请保留原文出处、译者和译文链接。 ] 转载于:https://my.oschina.net/u/165124/blog/373724