java里modification_关于 java.util.ConcurrentModificationException 的认识

本文解析了在遍历ArrayList过程中添加元素导致ConcurrentModificationException异常的原因。深入探讨了ArrayList和LinkedList内部实现机制,特别是modCount变量的作用及其如何触发异常。并提供了解决方案。

今天在遍历arrayList的时候,添加了一些元素进去,然后抛出ConcurrentModificationException 这个异常。然后就去网上找了下资料,抛出这个异常的原因是因为,list 集合 在遍历的时候是不允许修改list的。实质是不允许修改当前遍历list的长度的。

在 arrayList 和 linkedList 的实现里 都一个 modCount 这个遍历。 对于arrayList,在调用remove 和 clean 方法的时候,会修改 modCount 这个变量的值。在遍历的时候这个值被修改了。就会报错。 但我是对arrayList 添加元素。并不是删除,按理来说是不会修改modCount 这个值的。 可还是报错了。后来查看了源码。arrayList是用数组实现的。当你添加元素的时候,实现是会去检查数组的大小,是否需要扩容。问题就在这里,在扩容的时候,是会修改modCount 这个值的。

代码入下

public boolean add(E e) {

ensureCapacityInternal(size + 1); // Increments modCount!! 次方法用来检查是否要扩大数组的大小

elementData[size++] = e;

return true;

}

private void ensureCapacityInternal(int minCapacity) {

if (elementData == EMPTY_ELEMENTDATA) {

// 加入 数组还是为空话,选择默认的大小

minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);

}

//扩大数组的大小

ensureExplicitCapacity(minCapacity);

}

private void ensureExplicitCapacity(int minCapacity) {

modCount++;

// overflow-conscious code 传入进来的容量必须大于当前的容量

if (minCapacity - elementData.length > 0)

grow(minCapacity);

}

对于linkedList 的话 你调用add 方法的时候就直接修改modCount 的值了。 因为linkedList是用链表实现的。所以每一次添加其实都是在修改集合的大小。

private void linkFirst(E e) {

final Node f = first;

final Node newNode = new Node<>(null, e, f);

first = newNode;

if (f == null)

last = newNode;

else

f.prev = newNode;

size++;

modCount++;

}

那我们需要就是要修改大小怎么办呢?

对于 删除元素的话,我们可以用迭代器,然后使用迭代器的 remove 的方法。这个是对于删除来说比较通用的方法。

假如是要添加元素的的话。我没有找到很好的方法。我是用另外要给list 暂时存放需要的添加的元素。等遍历完以后,再把,需要添加的元素一起放进去。不知哪位高人有更好的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值