java - 迭代时移除元素。removeIf 导致 ConcurrentModificationException
问题描述
我试图在循环遍历集合时从集合(someObjectSet)中删除元素。正如我用谷歌搜索的那样,在这种情况下使用 removeIf 应该避免 ConcurrentModificationException 。但是,这对我不起作用。
谷歌是否对我撒谎(或者我误解了它),或者我没有正确使用 removeIf?
Set<SomeObject> someObjectSet = new HashSet<>();
someObjectSet.add(obj1);
someObjectSet.add(obj2);
someObjectSet.add(obj3);
for (SomeObject obj : someObjectSet ){
...
someObjectSet.removeIf(ele -> if ele satisfies some condition)
}
我想在循环内执行 removeif 的原因是,在每个循环中,可以确定集合的其他一些元素不再需要进入循环,因此我将其删除以便 for 循环不会不要再接他们了。
例如,
在 loop1 中,obj1
被选中。
然后在同一个循环中,它发现obj2
不再需要处理 =>obj2
从集合中删除。
在 loop2 中,而不是obj2
,obj3
被拾取
提前致谢!
解决方案
不要迭代和removeIf
使用迭代的元素。除了您现在遇到的问题之外,这些调用相当于为集合的每个元素迭代整个集合(因此您在迭代时仍然从集合中删除,这解释了异常!)。
removeIf
为你迭代,所以你只需要一个谓词SomeObject
:
//no loop
someObjectSet.removeIf(ele -> if ele satisfies some condition);
每个元素将被测试ele -> if ele satisfies some condition
的条件在哪里(通过测试的元素将被删除)。将对中的所有元素编排测试,您不需要这样做。SomeObject
forEach
someObjectSet
如果您有要删除元素的次要条件,那么您可以组合谓词(使用or
),如下例所示:
Set<Integer> set = new HashSet<>(Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
Predicate<Integer> predicate = s -> s % 2 == 0;
Predicate<Integer> predicate2 = predicate.or(s -> s % 3 == 0);
set.removeIf(predicate2);
// Test with set.removeIf(predicate);
// then with set.removeIf(predicate2);
// and compare results
推荐阅读
- mongodb - 在一个查询中插入多个文档,只有一个字段不同 | 蒙哥
- python - 绕过单击并按住 python selenium
- c++ - 为什么当为格式标识符(%s)分配一个在c ++中返回字符串的函数时,printf会抛出错误?
- typescript - 停止加载 Vue 页面,直到加载数据(获取)
- shell - sed 一次处理多行
- html - 有没有办法在导航栏顶部添加一个框?
- c++ - 模板内的 C++ value_type::second_type 编译器错误
- c++ - Which of two conversion operators must be selected by C++ compiler?
- regex - 如何在 PowerShell 中使用递归正则表达式来查找嵌套括号
- wkwebview - 如何在 WKWebView 中从本地加载 WebWorker