ArrayList

作者: 森林中大鸟 | 来源:发表于2020-05-17 23:58 被阅读0次

    ArrayList foreach删除元素报错分析

    List<String> a = new ArrayList<String>(); 
        a.add("1");
        a.add("2");
        for (String temp : a) { 
            if("1".equals(temp)){
                a.remove(temp); 
        } 
    } 
    

    以上代码对应class文件如下:

    List a = new ArrayList();
    a.add("1");
    a.add("2");
    Iterator i$ = a.iterator();
    do
    {
        if(!i$.hasNext())
            break;
        String temp = (String)i$.next();
        if("1".equals(temp))
            a.remove(temp);
    } while(true);
    

    场景一

     List<String> a = new ArrayList<String>(); 
     a.add("1");
     a.add("2");
     for (String temp : a) { 
        if("1".equals(temp)){
             a.remove(temp); 
         } 
     } 
    

    执行结果

    删除不会报错,但是循环只走了一次就结束了。

    原因

    for循环实际相当于使用迭代器遍历,在第一次循环时,执行完next()方法后游标置为1,即如下代码中第9行 cursor = 1

    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
        throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
        throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }
    

    接着执行remove(),执行成功后 size-1。
    进行下次循环时执行hasNext()判断是否存在下一个元素时 满足cursor!=size 为true
    ,因此循环结束,代码如下:

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

    场景二

     List<String> a = new ArrayList<String>(); 
     a.add("1");
     a.add("2");
     for (String temp : a) { 
        if("2".equals(temp)){
             a.remove(temp); 
         } 
     } 
    

    执行结果

    删除之后,报错。

    原因

    for 在第二次循环中,执行完remove(),size=1,此时因为循环执行过两次,因此 此时cursor = 2,在进行第三次循环前 会执行 hasNext(),此时size != cursor 成立,导致 hasNext() 结果为true ,进入循环,然后执行next()方法。
    next()方法会判断修改次数与预期修改次数是否相等,因为直接调用ArrayList的remove方法修改了modCount(+1)但不会修改得迭代器中的 expectedModCount的值,因此 出现
    ConcurrentModificationException

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

    相关文章

      网友评论

          本文标题:ArrayList

          本文链接:https://www.haomeiwen.com/subject/cxcyohtx.html