Java Or android ConcurrentModificationException异常原因和解决方法

拜拜、爱过 提交于 2020-03-05 07:14:37

 ArrayList<Integer> list = new ArrayList<Integer>();

        list.add(2);

        Iterator<Integer> iterator = list.iterator();

        while(iterator.hasNext()){

            Integer integer = iterator.next();

            if(integer==2)

                list.remove(integer);

        }

 

运行结果:

  

从异常信息可以发现,异常出现在checkForComodification()方法中。

  我们不忙看checkForComodification()方法的具体实现,我们先根据程序的代码一步一步看ArrayList源码的实现:

  首先看ArrayList的iterator()方法的具体实现,查看源码发现在ArrayList的源码中并没有iterator()这个方法,那么很显然这个方法应该是其父类或者实现的接口中的方法,我们在其父类AbstractList中找到了iterator()方法的具体实现,下面是其实现代码:

1

2

3

public Iterator<E> iterator() {

    return new Itr();

}

   从这段代码可以看出返回的是一个指向Itr类型对象的引用,我们接着看Itr的具体实现,在AbstractList类中找到了Itr类的具体实现,它是AbstractList的一个成员内部类,下面这段代码是Itr类的所有实现:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

private class Itr implements Iterator<E> {

    int cursor = 0;

    int lastRet = -1;

    int expectedModCount = modCount;

    public boolean hasNext() {

           return cursor != size();

    }

    public E next() {

           checkForComodification();

        try {

        E next = get(cursor);

        lastRet = cursor++;

        return next;

        catch (IndexOutOfBoundsException e) {

        checkForComodification();

        throw new NoSuchElementException();

        }

    }

    public void remove() {

        if (lastRet == -1)

        throw new IllegalStateException();

           checkForComodification();

 

        try {

        AbstractList.this.remove(lastRet);

        if (lastRet < cursor)

            cursor--;

        lastRet = -1;

        expectedModCount = modCount;

        catch (IndexOutOfBoundsException e) {

        throw new ConcurrentModificationException();

        }

    }

 

    final void checkForComodification() {

        if (modCount != expectedModCount)

        throw new ConcurrentModificationException();

    }

}

   首先我们看一下它的几个成员变量:

  cursor:表示下一个要访问的元素的索引,从next()方法的具体实现就可看出

  lastRet:表示上一个访问的元素的索引

  expectedModCount:表示对ArrayList修改次数的期望值,它的初始值为modCount。

  modCount是AbstractList类中的一个成员变量

1

protected transient int modCount = 0;

   该值表示对List的修改次数,查看ArrayList的add()和remove()方法就可以发现,每次调用add()方法或者remove()方法就会对modCount进行加1操作。

总结:

如果使用Iterator对集合进行增或者删操作,请在Iterator体制内调用对应的方法操作。直白点说就是如果你使用了Iterator,就不要直接调用表层集合的list.add(Object),list.remove(obj)了。因为Iterator里面有个modCount==0,如果你调用了表层的方法,modCount就要重新赋值,导致,modCount!=expectedModCount值,从而抛出了 ConcurrentModificationException

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!