资讯专栏INFORMATION COLUMN

关于 java.util.ConcurrentModificationException 的认识

骞讳护 / 3141人阅读

摘要:今天在遍历的时候,添加了一些元素进去,然后抛出这个异常。实质是不允许修改当前遍历的长度的。并不是删除,按理来说是不会修改这个值的。是用数组实现的。这个是对于删除来说比较通用的方法。我是用另外要给暂时存放需要的添加的元素。

今天在遍历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 暂时存放需要的添加的元素。等遍历完以后,再把,需要添加的元素一起放进去。不知哪位高人有更好的方法。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66603.html

相关文章

  • ConcurrentModificationException,iterator迭代问题[源码分析]

    摘要:单线程的迭代过程中删除集合元素以上代码会出现如下异常从后往前看第行代码我们在执行代码行时调用了这个是调用返回的对象这个对象的方法如下图方法首先它会调用这个方法这个方法很简单就是比较这两个值是不是相等不相等就抛出异常如下图这两个值为什么会不相 单线程的Iterator迭代过程中删除集合元素 public class TestIterator { public static voi...

    zhoutk 评论0 收藏0
  • ConcurrentModificationException,iterator迭代问题[源码分析]

    摘要:单线程的迭代过程中删除集合元素以上代码会出现如下异常从后往前看第行代码我们在执行代码行时调用了这个是调用返回的对象这个对象的方法如下图方法首先它会调用这个方法这个方法很简单就是比较这两个值是不是相等不相等就抛出异常如下图这两个值为什么会不相 单线程的Iterator迭代过程中删除集合元素 public class TestIterator { public static voi...

    aaron 评论0 收藏0
  • ConcurrentModificationException,iterator迭代问题[源码分析]

    摘要:单线程的迭代过程中删除集合元素以上代码会出现如下异常从后往前看第行代码我们在执行代码行时调用了这个是调用返回的对象这个对象的方法如下图方法首先它会调用这个方法这个方法很简单就是比较这两个值是不是相等不相等就抛出异常如下图这两个值为什么会不相 单线程的Iterator迭代过程中删除集合元素 public class TestIterator { public static voi...

    junnplus 评论0 收藏0
  • LinkedList实现

    package com.nasuf.arraylist; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.NoSuchElementException; public class MyLinkedList implements Iterable { ...

    yimo 评论0 收藏0
  • Java中如何优雅地删除List中元素

    摘要:删除元素后,立即跳出,则正常退出,但不能向后继续循环了删除后立马终端循环,会正常跳出,但代价是不能继续向后循环了使用迭代器使用迭代器可,正确无误的删除,代码简洁优雅,推荐使用使用迭代器可,正确无误的删除注意这里时而不是 在工作中的许多场景下,我们都会使用到List这个数据结构,那么同样的有很多场景下需要删除List中的某一个元素或某几个元素,那么我们该如何正确无误地删除List中的元素...

    kelvinlee 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<