list遍历删除元素

场景是,需要删除objList中的某几个元素,自然而然,我们会习惯性的写下如下语句:

for(Object o : objList)  
{  
    if(o == value)  
   {  
       objList.remove(i);   
   }  
   i++;  
}  

报错

这时你就会发现报 java.util.ConcurrentModificationException 异常,此异常是迭代器抛出的异常,官方说明是:

The Iterators returned by this class’s iterator method are fail-fast: if the set is modified at any time after the iterator is created, in any way except through the iterator’s own remove method, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

大概意思是:在用迭代器迭代集合的时候,迭代器一旦创建,就不允许更改集合,如果所迭代的集合(Set或者List)的有修改的话,就会抛出
ConcurrentModificationException异常, 用迭代器自身的remove方法除外…

解决方法

如何在遍历过程中正确的删除指定元素呢?

一. 用一个List 记录要删除的数据,最后removeAll(List);

List<Integer> removeList = new ArrayList()  
for(Integer i : intList)  
{  
    if(i == obj)  
    {  
        removeList.add(i);  
    }  
}  
//最后  
if(removeList.size()>0)  
{  
    intList.removeAll(removeList);  
}

二.用for循环遍历,原始书写方式

for(int i = 0; i < intList.size(); i++)  
{  
    if(intList.get(i) == obj)  
    {  
        intList.remove(i);  

        //此时要注意,因为list会动态变化不像数组会占位,所以当前索引应该后退一位  
        i--;  
    }  
}

三.用迭代器自带的remove方法,这也是官方推荐的方法

Iterator <Integer> it = intList.iterator();  
while(it.hasNext())  
{  
    if(it.next() == obj)  
    {  
        it.remove();  
    }  
}

四.使用 CopyOnWriteArrayList 创建一个线程安全的集合

  • CopyOnWriteArrayList 介绍

    这是一个ArrayList的线程安全的变体,其原理大概可以通俗的理解为:初始化的时候只有一个容器,很常一段时间,这个容器数据、数量等没有发生变化的时候,大家(多个线程),都是读取(假设这段时间里只发生读取的操作)同一个容器中的数据,所以这样大家读到的数据都是唯一、一致、安全的,但是后来有人往里面增加了一个数据,这个时候CopyOnWriteArrayList 底层实现添加的原理是先copy出一个容器(可以简称副本),再往新的容器里添加这个新的数据,最后把新的容器的引用地址赋值给了之前那个旧的的容器地址,但是在添加这个数据的期间,其他线程如果要去读取数据,仍然是读取到旧的容器里的数据。

List<Integer> list=new ArrayList<Integer>();
CopyOnWriteArrayList<Object> copyList=new CopyOnWriteArrayList<Object>(list);
for(Integer data:copyList) 
{
    if(data.equals(obj)) 
    {
        list.remove(data);
    }
}

猜你喜欢

转载自blog.csdn.net/BeiShangBuZaiLai/article/details/81565602