• 记一次list循环删除元素的突发事件!


    事情是这样的,由于想再回顾一下基础,就写了一个main函数,里面循环删元素的代码。如下:

    List<String> a = new ArrayList<String>();
    a.add("a");
    a.add("b");
    for (String temp : a)
    {
    if("a".equals(temp)){
    a.remove(temp);
    }
    }
    System.out.println( a.toString());

    那么正常情况下我预期是会报异常 :Exception in thread "main" java.util.ConcurrentModificationException

    但是,结果确是正常删除了。。而且打印出了结果~~着实吓了我一跳,没有异常。。。然后就修改了代码将删除a换成了b,结果是报了异常了!!!哎,这下就纳闷了,这是为什么呢!!!

    然后就看了下remove方法的源码~发现报异常的原因是每当我们add的时候modcount就会加1,这个时候,还有一个expectedModCount 默认是将modcount 赋值给他,每当我们删除了一个元素那么remove 方法会先调用checkForComodification()再调用里面的一个fastremove方法,在这个方法里面会再执行modCount++; 

    在checkForComodification方法中进行的操作是:

    final void checkForComodification() {
        if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }
    如果modCount不等于expectedModCount,则抛出ConcurrentModificationException异常。
     
    那为什么第一个可以正常删呢~这个时候我又增加了若干元素,经过验证得知,在整个集合中的倒数第二个位置的元素,进行删除操作是不会报异常的,为什么呢?
    修改代码,在每次循环时打印输出元素

    List<String> a = new ArrayList<String>();
    a.add("a");
    a.add("b");
    a.add("c");
    a.add("d");
    a.add("e");
    for (String temp : a)
    {
    if("d".equals(temp)){
    a.remove(temp);
    }
    System.out.println( temp.toString());
    }
    System.out.println( a.toString());

    }

    这个时候的输出结果为:

    a
    b
    c
    d
    [a, b, c, e]

    看结果是没有再循环e删除完d就结束了~

    由于当删除完d元素后,后面的元素会自动向前移动,然后把最后的元素置位null,也就是告诉gc可以回收了。那么这个时候整个的size就变成了4,固到此就会认为整个循环结束,所以没有报异常。。。

     

     

    give me the ball!
  • 相关阅读:
    [导入]对字符串进行SHA1和DES(加密,解密),加密和解密的类
    [导入]在DropDownList 中添加"请选择"
    [导入]GridView中添加层,点击打开,展开此层,反之
    [导入]中文的SqlHelper.cs类
    [导入]怎样从ASP.NET 2.0中读取连接字符串
    项目主管做的事
    [导入]用.NET轻松分析字符串值
    [导入]SQL 缓存失效 2.0 版中的新增功能
    [导入]ListBox绑定数据,从左边移到右边的ListBox
    [导入]GridView 自定义分页
  • 原文地址:https://www.cnblogs.com/JJJ1990/p/7833039.html
Copyright © 2020-2023  润新知