从列表中删除项目

Tec*_*hie 101 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如何才能做到这一点?

Joo*_*gen 215

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

进一步假设列表是字符串.如已经回答的那样,list.iterator()需要一个.该的ListIterator可以做一些导航了.

  • 如果您的列表是由 Arrays.asList(arr) 形成的,则可能会抛出 UnsupportedOperationException,因为 Arrays.asList() 为您提供了一个固定列表。在这种情况下,执行 List&lt;E&gt; myList = new ArrayList&lt;&gt;(Arrays.asList(arr)) ,然后在列表上使用 listIterator 。如果您想用使用removeIf()的Java 8方法替换另一个,同样如此... (3认同)

kos*_*osa 72

您需要使用Iterator和调用remove()iterator,而不是使用for循环.


Sur*_*tta 30

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

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

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


And*_*nek 18

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

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

  • @AlexVentura这是因为迭代器模式的工作原理.如果迭代器引用的列表在没有迭代器知道的情况下引用了更改(特别是它的大小),则迭代器将"混乱". (3认同)

Bar*_*aar 7

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

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

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

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

List<T> filteredList = new Arraylist<>(filter(list, not(XXX_EQUAL_TO_AAA)));
Run Code Online (Sandbox Code Playgroud)

然后在其他地方将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");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这可能在你的情况下有点过头了.随着集合的使用越多,它就越强大.

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

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;
Run Code Online (Sandbox Code Playgroud)


Mak*_*kky 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);
Run Code Online (Sandbox Code Playgroud)

  • 为何如此复杂...... (4认同)
  • 它并不复杂.它是另一种从另一个列表中删除列表的方法. (4认同)
  • 您不需要时创建一个新对象,并且可能两次循环列表. (4认同)