AFAIK,有两种方法:

迭代集合的副本 使用实际集合的迭代器

例如,

List<Foo> fooListCopy = new ArrayList<Foo>(fooList);
for(Foo foo : fooListCopy){
    // modify actual fooList
}

and

Iterator<Foo> itr = fooList.iterator();
while(itr.hasNext()){
    // modify actual fooList using itr.remove()
}

是否有任何理由偏爱一种方法而不是另一种方法(例如,出于可读性的简单原因而偏爱第一种方法)?


当前回答

在Java 8中,还有另一种方法。# removeIf集合

eg:

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);

list.removeIf(i -> i > 2);

其他回答

为什么不是这个?

for( int i = 0; i < Foo.size(); i++ )
{
   if( Foo.get(i).equals( some test ) )
   {
      Foo.remove(i);
   }
}

如果它是映射,而不是列表,你可以使用keyset()

只有第二种方法有效。只能在迭代过程中使用iterator.remove()修改集合。所有其他尝试都会导致ConcurrentModificationException。

我会选择第二个,因为你不需要复制内存,迭代器工作得更快。这样可以节省内存和时间。

旧时最爱(现在还能用):

List<String> list;

for(int i = list.size() - 1; i >= 0; --i) 
{
        if(list.get(i).contains("bad"))
        {
                list.remove(i);
        }
}

好处:

它只在列表上迭代一次 没有创建额外的对象或其他不必要的复杂性 尝试使用已删除项的索引没有问题,因为…好吧,想想看!

你可以看到这个例子;如果我们考虑从列表中移除奇数值:

public static void main(String[] args) {
    Predicate<Integer> isOdd = v -> v % 2 == 0;
    List<Integer> listArr = Arrays.asList(5, 7, 90, 11, 55, 60);
    listArr = listArr.stream().filter(isOdd).collect(Collectors.toList());
    listArr.forEach(System.out::println);
}