从集合中删除项将调用java.util.ConcurrentModificationException



我尝试从两个排序列表创建排名。

 List<Ordered<String>> rankedList = Collections.synchronizedList(WebCBIR.run(queryData, clusters, idf));
 List<Ordered<String>> rankedList2 = Collections.synchronizedList(WebCBIR.run(queryData, clusters));
 LinkedList<Ordered<String>> result = new LinkedList<>();
 Iterator<Ordered<String>> it = rankedList.iterator();
 Iterator<Ordered<String>> it2 = rankedList2.iterator();
 while (it.hasNext() && it2.hasNext())  {
        Ordered<String> o1 = it.next();
        Ordered<String> o2 = it2.next();
        Ordered<String> o = null;
        if(o1.value() > o2.value()){
            o = o1;
            rankedList.remove(o);
            rankedList2.remove(o);
        }
        else{
            o = o2;
            rankedList.remove(o);
            rankedList2.remove(o);
        }
        result.add(o);
}

此代码调用java.util.ConcurrentModificationException。如何处理?

当使用迭代器时,不要从List中删除,而是使用iterator.remove()方法

while (it.hasNext() && it2.hasNext())  {
        Ordered<String> o1 = it.next();
        Ordered<String> o2 = it2.next();
        Ordered<String> o = null;
        if(o1.value() > o2.value()){
            o = o1;
            it.remove();
            it2.remove();
        }
        else{
            o = o2;
            it.remove();
            it2.remove();
        }
        result.add(o);
}

不能在迭代Collection的同时修改它

在使用迭代器遍历一个集合时修改它的唯一方法是通过迭代器本身。由于您希望通过删除可能不是其中一个迭代器当前元素的元素来修改两个集合,因此不能使用Iterator.remove()。我建议累积一组要删除的元素,然后在迭代完成后再全部删除。由于您已经在result中积累了,您可以使用:

while (it.hasNext() && it2.hasNext())  {
    Ordered<String> o1 = it.next();
    Ordered<String> o2 = it2.next();
    Ordered<String> o = o1.value() > o2.value() ? o1 : o2;
    result.add(o);
}
rankedList.removeAll(result);
rankedList2.removeAll(result);

最新更新