我是靠谱客的博主 精明麦片,最近开发中收集的这篇文章主要介绍JAVA集合中删除元素时的java.util.ConcurrentModificationException,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
在JAVA的集合(LIST,SET)中通过iterator.hasNext() 或者iterator.next()遍历集合中的数据时,如果这时候add或者remove集合中的元素,会发生ConcurrentModificationException异常.
本文简单说明一下这种现象和解决方法.
如下面的代码,不管是remove还是add都会发生ConcurrentModificationException异常.
public static void testWrongAccess2() {
Collection<String> myCollection = new ArrayList<String>(10);
myCollection.add("1");
myCollection.add("2");
myCollection.add("3");
myCollection.add("4");
Iterator itr = myCollection.iterator();
while (itr.hasNext()) {
String myObject = (String) itr.next();
System.out.println(myObject);
if ("2".equals(myObject)) {
myCollection.remove(myObject); // cause ConcurrentModificationException
//myCollection.add("4"); // cause ConcurrentModificationException
}
}
}
//1.5之后的写法也是会有异常的
for (String myObject: myCollection) {
System.out.println(myObject);
if ("2".equals(myObject)) {
myCollection.remove(myObject);
}
}
关于remove的解决办法是:利用iterator的remove方法.
public static void testRightAccess() {
Collection<String> myCollection = new ArrayList<String>(10);
myCollection.add("1");
myCollection.add("2");
myCollection.add("3");
myCollection.add("4");
Iterator itr = myCollection.iterator();
while (itr.hasNext()) {
String myObject = (String) itr.next();
System.out.println(myObject);
if ("2".equals(myObject)) {
itr.remove();
}
}
}
对于在集合满足某种条件的情况下add元素的解决:先将要add的元素放在另外一个集合里,在判断遍历完成后在加入.
public static void testRightAccess2() {
Collection<String> myCollection = new ArrayList<String>(10);
myCollection.add("1");
myCollection.add("2");
myCollection.add("3");
myCollection.add("4");
Collection<String> tempCollection = new ArrayList<String>(10);
Iterator itr = myCollection.iterator();
while (itr.hasNext()) {
String myObject = (String) itr.next();
if ("1".equals(myObject)) {
tempCollection.add("1 Exists");
}
if ("2".equals(myObject)) {
tempCollection.add("2 Exists");
}
}
myCollection.addAll(tempCollection);
}
这里碰到一个有趣的现象:下面的代码没有发生ConcurrentModificationException,在一个只有3个元素的集合中,remove第二个元素,没有ConcurrentModificationException发生而且最后集合里只有1和3,remove 1 和 3 都会有异常,add元素也会有异常,难道是JDK的bug??总之,在remove元素的时候应该用iterator的remove方法.
public static void testWrongAccess1() {
Collection<String> myCollection = new ArrayList<String>(10);
myCollection.add("1");
myCollection.add("2");
myCollection.add("3");
Iterator itr = myCollection.iterator();
while (itr.hasNext()) {
String myObject = (String) itr.next();
System.out.println(myObject);
if ("2".equals(myObject)) {
myCollection.remove(myObject); // doesn't cause ConcurrentModificationException
//myCollection.add("4"); // cause ConcurrentModificationException
}
}
}
如果想在读取的同时进行修改,可以用CopyOnWriteArrayList或者CopyOnWriteArraySet
public class CopyOnWriteDemo {
public static void main(String args[]) {
String[] ss = { "aa", "bb", "cc" };
List list1 = new CopyOnWriteArrayList(Arrays.asList(ss));
List list2 = new ArrayList(Arrays.asList(ss));
Iterator itor1 = list1.iterator();
Iterator itor2 = list2.iterator();
list1.add("New");
list2.add("New");
try {
printAll(itor1);//不会异常
} catch (ConcurrentModificationException e) {
System.err.println("Shouldn't get here");
e.printStackTrace();
}
try {
printAll(itor2);//ConcurrentModificationException 异常
} catch (ConcurrentModificationException e) {
System.err.println("Will get ConcurrentModificationException");
e.printStackTrace();
}
//这里会把new打印出来
Iterator itor3 = list1.iterator();
try {
printAll(itor3);
} catch (ConcurrentModificationException e) {
System.err.println("Will get ConcurrentModificationException");
e.printStackTrace();
}
}
private static void printAll(Iterator itor) {
while (itor.hasNext()) {
System.out.println(itor.next());
}
}
}
最后
以上就是精明麦片为你收集整理的JAVA集合中删除元素时的java.util.ConcurrentModificationException的全部内容,希望文章能够帮你解决JAVA集合中删除元素时的java.util.ConcurrentModificationException所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复