[英]Removing element while iterating through it. removeIf result in ConcurrentModificationException
I'm trying to remove elements from a set (someObjectSet) while looping through it.我试图在循环时从集合 (someObjectSet) 中删除元素。 As I googled, using removeIf should avoid ConcurrentModificationException in this case.
正如我用谷歌搜索的那样,在这种情况下使用 removeIf 应该避免 ConcurrentModificationException 。 However this doesn't work for me.
然而这对我不起作用。
Did google lied to me (or I misundertood it), or I'm not using removeIf correctly?谷歌是否对我撒了谎(或者我误解了它),或者我没有正确使用 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)
}
The reason I want to do removeif inside the loop is that, in each loop, it can be determined that some other elements of the set no longer need to go in the loop, therefore I'm removing it so that the for loop won't pick them up again.我想在循环内执行 removeif 的原因是,在每个循环中,可以确定集合的其他一些元素不再需要进入循环,因此我将其删除,以便 for 循环将不要再捡起来。
For example,例如,
In loop1, obj1 gets picked.在 loop1 中,obj1 被选中。
Then in the same loop it finds out obj2 no longer needs to be processed => remove obj2 from the set.然后在同一个循环中,它发现不再需要处理 obj2 => 从集合中删除 obj2。
In loop2, instead of obj2, obj3 is picked up在loop2中,拾取的是obj3而不是obj2
Thanks in advance!提前致谢!
Don't iterate and removeIf
using elements of your iteration.不要使用迭代的元素进行迭代和
removeIf
。 Beside the problem you're experiencing right now, those calls amount to iterating through the entire collection for each element of the collection (so you're still removing from the collection while iterating, which explains the exception!).除了您现在遇到的问题之外,这些调用相当于为集合的每个元素遍历整个集合(因此您在迭代时仍然从集合中删除,这解释了异常!)。
removeIf
iterates for you, so all you need is a predicate of SomeObject
: removeIf
为您迭代,所以您只需要SomeObject
的谓词:
//no loop
someObjectSet.removeIf(ele -> if ele satisfies some condition);
Where ele -> if ele satisfies some condition
is the condition that each SomeObject
element will be tested against (the ones passing the test will be removed). where
ele -> if ele satisfies some condition
是每个SomeObject
元素将被测试的条件(通过测试的元素将被删除)。 forEach
will orchestrate the test on all elements in someObjectSet
, you don't need to do that. forEach
将对someObjectSet
所有元素编排测试,您不需要这样做。
If you're having a secondary condition based on which you want to remove elements, then you can compose predicates (with or
), something like in this example:如果您有基于要删除元素的辅助条件,那么您可以组合谓词(使用
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.