从列表中删除项目

时间:2013-06-24 15:40:51

标签: java collections

循环浏览列表时,我想根据条件删除列表项。请参阅下面的代码。

这给了我一个ConcurrentModification例外。

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

如何做到这一点?

6 个答案:

答案 0 :(得分:206)

for (Iterator<String> iter = list.listIterator(); iter.hasNext(); ) {
    String a = iter.next();
    if (...) {
        iter.remove();
    }
}

进一步假设列表是字符串。 如前所述,需要list.iterator()listIterator也可以进行一些导航。

答案 1 :(得分:67)

您需要使用Iterator并在remove()上致电iterator,而不是使用for循环。

答案 2 :(得分:28)

你不能这样做,因为你已经在它上面循环。

为了避免这种情况,请使用Iterator,它可以保证您安全地从列表中删除元素......

List<Object> objs;
Iterator<Object> i = objs.iterator();
while (i.hasNext()) {
   Object o = i.next();
  //some condition
    i.remove();
}

答案 3 :(得分:18)

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

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

答案 4 :(得分:7)

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

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

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

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

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");
    }
}

然而,这可能是你的情况有点过分。随着集合的使用越多,它就会变得越来越强大。

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

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

答案 5 :(得分:5)

//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);