我遇到了以下问题:
给定一个列表(让我们称其为ArrayList ),我如何在不获取ConcurrentModificationException的情况下对其进行“双重迭代”?
这是我尝试过的:
iterator out = list.iterator();
iterator in;
while(out.hasNext()){
...
in = list.iterator();
while(in.hasNext()){
...
if(something)
in.remove();
}发布于 2017-06-09 16:59:38
你不能这么做。一个潜在的解决方案可能是标记要删除的对象,例如:
final List<Foo> toRemove = new ArrayList<>();
for (Foo a : list)
{
for (Foo b : list)
{
if (something)
{
toRemove.add(b);
}
}
}
list.removeAll(toRemove);您可能需要一些额外的检查,以查看该对象是否已标记为要删除。鉴于你的例子是多么模糊,这是不可能说的。
发布于 2017-06-09 17:01:53
您正在尝试修改迭代器。它会给你一个concurrentModification异常。
在java 8中,您可以使用list.removeIf(someCondition)轻松地删除它。
尝试此链接java8 collections
发布于 2017-06-09 19:25:36
通过调用List#iterator方法提供的Iterator实例保留了一个计数标量,允许检测对Collection容器的外部更改。
当通过除通过相同的Iterator#remove(T)调用之外的任何其他方法从集合中移除元素时,计数不会在后台更新。因此,当您通过迭代器实例请求#next()元素时,将根据预期值检查计数,如果两个值不匹配(因为元素已通过另一个迭代器删除),则抛出ConcurrentModificationException (即使您可能在单线程环境中工作)。
正如@Michael所说,解决方案应该是跟踪应该删除的容器元素,然后执行批量删除:
Collection<Object> temp = new ArrayList<>();
iterator out = list.iterator();
iterator in;
while (out.hasNext()) {
// ...
in = list.iterator();
while (in.hasNext()) {
// ...
if(something)
// just mark the element for deletion
temp.add(in.next());
}
}
// delete all the obsolete elements
list.removeAll(temp);https://stackoverflow.com/questions/44453455
复制相似问题