从 foreach 中间的集合中删除多个元素安全吗?

Is removing multiple elements from a set in the middle of a foreach safe?

下面的代码安全吗?假设它是单线程的。

for(String s : set){
    set.remove(s);
    set.remove(randomElementFromSet());
}

我很确定这应该没问题,但我想仔细检查我 运行 没有迭代已经删除的元素的风险。

另外,如果可以的话,请提供参考,以便我下次查看。

你试过了吗?你会得到 ConcurrentModificationException。

在遍历集合时从集合中删除元素的一种安全方法是显式使用迭代器:

for(Iterator<String> iter = set.iterator(); iter.hasNext();) {
    String s = iter.next();
    iter.remove();
}

您不应使用 for-each 循环过滤集合,因为您可以获得 ConcurrentModificationException.

要正确执行此操作,您可以使用 IteratorremoveIf。这两段代码都打印 [Foo].

方法使用 Iterator:

Set<String> set = new HashSet<String>(Arrays.asList("Foo", "Bar", "Baz"));
for (Iterator<String> i = set.iterator(); i.hasNext();)
    if (i.next().contains("B"))
        i.remove();
System.out.println(set);

方法使用 removeIf (Java 8):

Set<String> set = new HashSet<>(Arrays.asList("Foo", "Bar", "Baz"));
set.removeIf(str -> str.contains("B"));
System.out.println(set);