在Map或者Collection的时候,不要用它们的API直接修改集合的内容(否则会出现 java.util.ConcurrentModificationException 异常),如果要修改可以用Iterator的remove()方法,例如:
Java代码
public void setReparation( Reparation reparation ) {
for (Iterator it = this.reparations.iterator();it.hasNext();){ //reparations为Collection
Reparation repa = (Reparation)it.next();
if (repa.getId() == reparation.getId()){
this.reparations.remove(repa);
this.reparations.add(reparation);
}
}
}
如上写会在运行期报ConcurrentModificationException,可以如下修改:
Java代码
public void setReparation( Reparation reparation ) {
boolean flag = false;
for (Iterator it = this.reparations.iterator();it.hasNext();){ //reparations为Collection
Reparation repa = (Reparation)it.next();
if (repa.getId() == reparation.getId()){
it.remove();
flag = true;
break;
}
}
if(flag){
this.reparations.add(reparation);
}
}
请问, 按照代码一写出现异常的原因是什么啊?
为什么使用 Iterator来删除集合里面的数据就没有异常呢?
引用
转:ConcurrentModificationException主要原因及处理方法
2007年04月18日 星期三 12:57
当使用 fail-fast iterator 对 Collection 或 Map 进行迭代操作过程中尝试直接修改 Collection / Map 的内容时,即使是在单线程下运行, java.util.ConcurrentModificationException 异常也将被抛出。
Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。
有意思的是如果你的 Collection / Map 对象实际只有一个元素的时候, ConcurrentModificationException 异常并不会被抛出。这也就是为什么在 javadoc 里面指出: it would be wrong to write a program that depended on this exception for its correctness: ConcurrentModificationException should be used only to detect bugs.
1 import java.util.*;
2
3 public final class MyTest
4 {
5 private static HashMap p_mapList = new HashMap(2);
6 private MyTest(){}
7 public static void init(){
8 // If only there are more than one element in Map,
9 // the ConcurrentModificationException will not be
10 // thrown.
11 p_mapList.put(new String("hello"),new String("world"));
12 p_mapList.put(new String("goto"),new String("hell"));
13 }
14 public static void clear() throws Exception{
15 Iterator pTmpKeys = null;
16 Long pTmpKeyLong;
17 pTmpKeys = p_mapList.keySet().iterator();
18 String pCurKey = null;
19 String pCurObj = null;
20 while(pTmpKeys.hasNext()){
21 pCurKey = (String) pTmpKeys.next();
22 pCurObj = (String) p_mapList.get(pCurKey);
23
24 p_mapList.put(pCurKey,null);
25 // You can not remove element in Map object directly.
26 //p_mapList.remove(pCurKey);
27 // But you can remove current element by iterator itself.
28 pTmpKeys.remove();
29
30 System.out.println(pCurKey + " removed.");
31 }
32 System.out.println(p_mapList.size() +
33 " entries left after iterator.");
34 pTmpKeys = null;
35 }
36 public static void main(String[] args)
37 throws Exception{
38 MyTest.init();
39 MyTest.clear();
40 }
41 }
分享到:
相关推荐
Java集合遍历的几种方式总结及详细比较 Java集合遍历是Java编程中最基本也是最重要的操作之一。集合遍历是指对集合中的每个元素进行访问和处理的过程。Java中提供了多种集合遍历方式,包括迭代器遍历、Map遍历、...
在JavaScript编程中,集合遍历和字符串操作是两个非常基础且重要的概念。在这个"js实例之集合遍历字符创修改"的主题中,我们将深入探讨如何使用JavaScript有效地遍历数组、对象集合以及如何对字符串进行修改。 首先...
Map集合遍历是日常开发中常见的操作,本篇将详细讲解五种不同的遍历方式,帮助初学者深入理解Java Map的使用。 1. **迭代器(Iterator)遍历** 这是最基本的遍历方式,通过Map接口提供的`iterator()`方法获取迭代...
"浅析Java 8中的集合遍历" Java 8中的集合遍历是一种非常重要的编程技术, Java平台提供了多种方式遍历对象的集合,其中包括今年3月19日发布的Java 8中引入的新特性。本文主要回顾了迭代器,着重分析了主动式迭代器...
在“TraversalPerformance.csproj”项目中,可能包含了编写这些集合遍历性能测试的代码。通过分析“Program.cs”和“Form1.cs”文件,我们可以找到测试用例的实现,包括遍历循环的逻辑和性能计时。`Form1.Designer....
List集合遍历和删除操作
在IT领域,构建树形结构的数据模型是一种...总之,一次集合遍历实现树形结构是Java和Spring Boot开发中处理层级数据的一种有效方法,它既简洁又高效。理解并掌握这种技巧,对提升后端服务的性能和可维护性大有裨益。
java List集合遍历测试 两个List,list1和list2.
一次集合遍历实现树形结构 - web
Java Collection 集合遍历运行代码实例 Java Collection 集合遍历是 Java 语言中最常用的数据结构之一。Collection 是 Java 集合框架中的一个接口,提供了基本的集合操作,例如添加、删除、遍历元素等。Collection ...
总结,Java集合遍历是日常开发中常见的操作,理解不同集合的遍历方式对于优化代码性能至关重要。本教程提供的源代码详细解释了ArrayList、LinkedList、HashSet和HashMap的遍历,以及Java 8的流API使用,有助于加深对...
Java实现Map集合遍历的四种常见方式与用法分析 Map集合是Java中的一种常见的数据结构,用于存储键值对形式的数据。在实际开发中,我们经常需要遍历Map集合来获取键和值。本文将介绍Java实现Map集合遍历的四种常见...
【Flutter】Dart 数据类型 Map 类型 ( 创建 Map 集合 | 初始化 Map 集合 | 遍历 Map 集合 ) https://hanshuliang.blog.csdn.net/article/details/113700234 博客源码快照
主要介绍了Java集合遍历实现方法及泛型通配,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Map的遍历大体有3种: 1、遍历Map.entrySet():它的每一个元素都是Map.Entry对象,这个对象中, ...3、遍历Map.values():它是Map中value的集合,我们可以直接通过这个集合遍历 Map中的值,却不能读取key。
集合类的对象增加删除和遍历,代码直接可以使用,eclipse调试过
#### 二、Map集合遍历方法 ##### 2.1 通过Map的keySet方法遍历 第一种遍历方式是通过`Map`的`keySet()`方法来获取所有键的集合,然后遍历这个键集,再通过键获取对应的值。 **示例代码:** ```java public void ...
集合遍历的重要性 集合框架是Java中非常基础且重要的组成部分之一,它提供了存储和管理对象的强大工具。在实际开发中,我们常常需要遍历集合中的每一个元素来进行数据处理或逻辑运算。因此,掌握一种高效且灵活的...
本文将通过一个具体的示例代码来详细介绍如何利用`Iterator`进行集合遍历。 #### 二、示例代码解析 在给定的代码片段中,我们看到的是使用Struts2标签库中的`<s:iterator>`标签来遍历一个名为`userlist`的集合对象...
总之,掌握Java集合遍历的基本方法并能灵活运用,是成为一名优秀Java开发者的基础。无论在实际开发还是面试中,这都是展示你编程功底的重要环节。只有扎实的基础,才能为后续的学习和实践打下坚实的基础,让你在IT...