使用for-each刪除list中的對象拋出 java.util.ConcurrentModificationException異常

使用for-each循環刪除時

Page<ReciprocateStrategy> reciprocateStrategyPage = reciprocateStrategyService.getReciprocateStrategyList(companyID, status, paginationParameters);
        for (ReciprocateStrategy reciprocateStrategy:reciprocateStrategyPage.getDataList()) {
            java.util.Date date=new java.util.Date();
            java.sql.Date sdate=new java.sql.Date(date.getTime());
            Date statusStartTime =reciprocateStrategy.getBeginTime();
            if(statusStartTime.getTime()>sdate.getTime()){
                reciprocateStrategyPage.getDataList().remove(reciprocateStrategy);
            }
        }

會拋出java.util.ConcurrentModificationException異常


原因:

用for-each遍歷 實際上使用的是Iterator迭代器
Iterator的工作機制:
Iterator是工作在一個獨立的線程中,並且擁有一個 mutex鎖,就是說Iterator在工作的時候,是不允許被迭代的對象被改變的。Iterator被創建的時候,建立了一個內存索引表(單鏈表),這 個索引表指向原來的對象,當原來的對象數量改變的時候,這個索引表的內容沒有同步改變,所以當索引指針往下移動的時候,便找不到要迭代的對象,於是產生錯 誤。List、Set等是動態的,可變對象數量的數據結構,但是Iterator則是單向不可變,只能順序讀取,不能逆序操作的數據結構,當 Iterator指向的原始數據發生變化時,Iterator自己就迷失了方向。

解決方法:

1、再定義一個List,用來保存需要刪除的對象:
修改部分代碼:
 List<User> userRemove = new ArrayList<User>();
        //找出要刪除的用戶
        System.err.println("要刪除的用戶:");
        for (User result : list)
        {
            if (result.getId() == 1 || result.getId() == 3)
            {
                userRemove.add(result);

                System.err.println("id:" + result.getId() + "\tname:" + result.getName());
            }
        }
        list.removeAll(userRemove);

        //剩下的用戶
        System.err.println("剩下的用戶:");
        for (User result : list)
        {
            System.err.println("id:" + result.getId() + "\tname:" + result.getName());
        }

2,不用for-each循環,用原始的書寫方式: 此方式如果按對象刪除可以如下寫、如果想按索引來刪除 請倒敘循環
for (int i = 0; i < list.size(); i++)
                {
                    User result = list.get(i);
                    if (result.getId() == 3)
                    {
                        list.remove(result);
                        System.err.println("id: " + result.getId() + "\tname: " + result.getName());
                    }
                }

3、用迭代器刪除
Iterator<User> it = list.iterator();
        while (it.hasNext())
        {
            User userObj = it.next();
            if (userObj.getId() == 3)
            {
                it.remove();
            }
        }
        //剩下的用戶
        System.err.println("剩下的用戶:");
        for (User result : list)
        {
            System.err.println("id:" + result.getId() + "\tname:" + result.getName());
        }


後修改爲:

Page<ReciprocateStrategy> reciprocateStrategyPage = reciprocateStrategyService.getReciprocateStrategyList(companyID, status, paginationParameters);
        for (int i = 0; i <reciprocateStrategyPage.getDataList().size(); i++) {
            java.util.Date date=new java.util.Date();
            java.sql.Date sdate=new java.sql.Date(date.getTime());
            ReciprocateStrategy reciprocateStrategy=reciprocateStrategyPage.getDataList().get(i);
            Date statusStartTime =reciprocateStrategy.getBeginTime();
            if(statusStartTime.getTime()>sdate.getTime()){
                reciprocateStrategyPage.getDataList().remove(reciprocateStrategy);
            }
        }
即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章