深究 java.util.ConcurrentModificationException

Exception in thread “main” java.util.ConcurrentModificationException

最近在对list 容器内进行遍历删除修改对象的时候报了这个错,问了下大佬自己去也去研究了一下,最后终于找到了原因,记个笔记。

一个简单的列子:

ArrayList<human> humans = new ArrayList<human>();
		
		for(int i=0; i<10 ;i++) {
			humans.add(new human(i));
		}
		for(human hu : humans) {
			humans.remove(hu);
		}
Iterator<human> it = humans.iterator();
	while(it.hasNext()) {
		human hu = it.next();
		humans.remove(hu);
		humans.add(hu);
	}

执行上述任何一个代码会抛出 java.util.ConcurrentModificationException 异常。
所以foreach遍历list 里面还是调用了iterator进行迭代遍历的,那为什么会出现这个问题?

跟踪一下remove方法
remove内fastRemove
发现有一个可疑的变量。
在这里插入图片描述这里还提示了增加modCount
在这里插入图片描述并且在其他只要是修改的方法也都会有这个变量。
接下
接着看下是怎么获取的.iterator();
是list的一个内部类并实现了Iterator接口
从next方法中看到其在每次获取下一个内容前都会进行某些检查,检查是否被修改。
在这里插入图片描述那么到这里已经知道缘由了,当对list对象进行增删操作的时候都会进行使modCount++,并且当iterator被创建的时候将当前的modCount 赋值给expectedModCount,每次迭代遍历前都会检查modCount是否被改变,改变就给你抛出异常。

q1 那为啥要阻止我们这么干?
q2 我就是要进行修改操作该咋办?

a1:
参考了几篇博客,自己做一个简单的总结:
执行以下代码进行模拟:

ArrayList<human> humans = new ArrayList<human>();
		humans.add(new human(a));
		humans.add(new human(b));
		humans.add(new human(c));
		humans.add(new human(d));
		Iterator<human> it = humans.iterator();
		human hu = it.next();
		

在这里插入图片描述执行上述代码数组容器是处于55行这样的一个情况,
但当我 再执行 humans.add(0,new human(x));
就变成了56行的样子,因为在数组前插入了一个数组导致了其他数据后移,此时就会导致少遍历数据了。因为next方法是返回内容并将指针后跳。但是插入删除都会造成其数组元素的移动,同理删除在某些情况也会影响,这里就不一一举例了。

a2:
iterator还提供了一个删除的方法可以快捷的删除内容。
`

 public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

通过一个lastRet定位当前节点的前一个节点,若前面一个节点内容被删除了就可以通过lastRet来处理元素变动的问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值