码迷,mamicode.com
首页 > 编程语言 > 详细

java修改集合抛出ConcurrentModificationException异常

时间:2015-08-19 17:57:08      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

测试代码为:

public static void main(String[] args) {
		List<String> strList = new ArrayList<String>();
		strList.add("1");
		strList.add("2");
		strList.add("3");
		strList.add("4");
		for(String str:strList){
			if(str.equals("4")){
				strList.remove(str);
			}
		}
	}

运行后结果如下:

技术分享

跟踪代码,抛出异常的地方具体在:

public E next() {
            checkForComodification();
	    try {
		E next = get(cursor);
		lastRet = cursor++;
		return next;
	    } catch (IndexOutOfBoundsException e) {
		checkForComodification();
		throw new NoSuchElementException();
	    }
	}

遍历时返回一个元素之前,会调用checkForComodification()函数进行检查,该函数实现为:

final void checkForComodification() {
	    if (modCount != expectedModCount)
		throw new ConcurrentModificationException();
	}

    modCount 为ArrayList修改的次数,expectedModCount 为期望修改的次数,在删除第四个元素之前,modCount 和expectedModCount 均为4,而调用ArrayList的remove()方法后,modCount 变为5,但expectedModCount 仍为4,因此出现上述异常。

    解决方法为:使用 Iterator的remove()方法取代ArrayList的remove()方法,可以避免ConcurrentModificationException异常。

    巧合的是,如果要删除的元素正好是集合中倒数第二个元素,则不会抛出此异常。Iterator遍历获取一个元素之前会先调用hasNext()方法来判断是否还有元素,该方法实现为:

public boolean hasNext() {
            return cursor != size();
	}

其中cursor为遍历的位置,从0开始,在上面的next()方法中更新。

    删除元素"3"后,cursor的值为3,而size()也返回3,hasNext()返回false,就不会调用next()方法了,因此也不存在ConcurrentModificationException异常

    删除元素"4"后,cursor的值变为4,而size()返回3,hasNext()返回true,调用next()方法时就会抛出ConcurrentModificationException异常



附上一篇资料:

Java ConcurrentModificationException异常原因和解决方法:http://www.cnblogs.com/dolphin0520/p/3933551.html








java修改集合抛出ConcurrentModificationException异常

标签:

原文地址:http://my.oschina.net/u/1375259/blog/494668

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!