2013-06-24 72 views
72

在循环显示列表时,我想根据条件删除列表中的项目。请参阅下面的代码。删除列表中的项目

这给我一个ConcurrentModification异常。

for (Object a : list) { 
    if (a.getXXX().equalsIgnoreCase("AAA")) { 
     logger.info("this is AAA........should be removed from the list "); 
     list.remove(a); 
    } 
} 

这怎么办?

+2

你不能从一个列表,而你遍历说列表中删除的元素。做一个副本并从中删除项目,或者直接对迭代器进行操作。 – thegrinner

回答

55

您需要使用Iterator并拨打而不是使用for循环。

3
//first find out the removed ones 

List removedList = new ArrayList(); 
for(Object a: list){ 
    if(a.getXXX().equalsIgnoreCase("AAA")){ 
     logger.info("this is AAA........should be removed from the list "); 
     removedList.add(a); 

    } 
} 

list.removeAll(removedList); 
+3

为什么这么复杂... – m0skit0

+4

它并不复杂。它是另一种从另一个列表中删除一个列表 – Makky

+3

当您不需要时,您正在创建一个新对象,并且可能还会循环两次。 – m0skit0

13

您不能也不应该修改列表而迭代它。您可以通过暂时保存要删除的对象来解决此问题:

List<Object> toRemove = new ArrayList<Object>(); 
for(Object a: list){ 
    if(a.getXXX().equalsIgnoreCase("AAA")){ 
     toRemove.add(a); 
    } 
} 
list.removeAll(toRemove); 
+0

为什么我不能在修改列表的同时迭代它? –

+2

@AlexVentura这是因为迭代器模式的工作原理。如果迭代器引用的列表发生变化(特别是它的大小)而没有迭代器知道,迭代器将会“搞砸”。 –

22

您不能这样做,因为您已经在循环它。

中序,以避免这种情况下使用Iterator,它guarentees您从列表中安全地删除元素...

List<Object> objs; 
Iterator<Object> i = objs.iterator(); 
while (i.hasNext()) { 
    Object o = i.next(); 
    //some condition 
    i.remove(); 
} 
155
for (Iterator<String> iter = list.listIterator(); iter.hasNext();) { 
    String a = iter.next(); 
    if (...) { 
     iter.remove(); 
    } 
} 

有一次额外的假设列表是一个字符串。 已经回答了,需要list.iterator()listIterator也可以做一些导航。

5

除了这里提供的所有优秀的解决方案,我想提供一个不同的解决方案。

我不确定您是否可以自由添加依赖项,但是如果可以的话,您可以将https://code.google.com/p/guava-libraries/作为依赖项添加。该库增加了对Java的许多基本功能操作的支持,并且可以使集合的工作更容易和更易读。

在代码中,我用T替换了列表的类型,因为我不知道你的列表输入了什么。

这个问题可以用番石榴可以解决这样的:

List<T> filteredList = new Arraylist<>(filter(list, not(XXX_EQUAL_TO_AAA))); 

而且别的地方即可定义为XXX_EQUAL_TO_AAA:

public static final Predicate<T> XXX_EQUAL_TO_AAA = new Predicate<T>() { 
    @Override 
    public boolean apply(T input) { 
     return input.getXXX().equalsIgnoreCase("AAA"); 
    } 
} 

但是,这是在您的情况可能是矫枉过正。只是随着收藏品的使用越多,它越强大。

OHW,还,你需要这些静态导入:

import static com.google.common.base.Predicates.not; 
import static com.google.common.collect.Collections2.filter;