这是与[FindBugs warning: Inefficient use of keySet iterator instead of entrySet iterator
类似的问题然而,我想尝试做一些不同的事情。我目前的代码在这里:
for (Double key2 : sortedPolygons.keySet()) {
if (sortedPolygons.get(key2).getExteriorRing().equals(hole)) {
sortedPolygons.remove(key2);
break;
}
}
在链接中执行类似解决方案的操作不起作用。以下是所述解决方案的实现:
for(Map.Entry<Double, Polygon> entry : sortedPolygons.entrySet()) {
if (entry.getValue().getExteriorRing().equals(hole)) {
.....
这里的问题是我正在尝试删除条目。没有entry.remove()
。如何在没有FindBugs错误的情况下替换我的第一个代码块:
低效使用keySet迭代器而不是entrySet迭代器 - &gt;
此方法使用的键访问Map条目的值 从keySet迭代器中检索。使用它更有效 地图的entrySet上的迭代器,以避免Map.get(键)查找。
要注意,底层结构为TreeMap
,无法更改。
答案 0 :(得分:5)
我无法理解你的推理:在第一个片段中,你使用
sortedPolygons.remove(key2);
删除密钥。没有什么能阻止你在第二个片段中做同样的事情:
sortedPolygons.remove(entry.getKey());
无论你如何迭代,这都会导致ConcurrentModificationException
,因为对于大多数集合,除非使用迭代器,否则在迭代时不能修改它。
引自the javadoc:
由所有类的“集合视图方法”返回的集合的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法,迭代器将抛出一个ConcurrentModificationException。
所以代码应该是:
for (Iterator<Map.Entry<Double, Polygon>> it = sortedPolygons.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<Double, Polygon> entry = it.next();
if (entry.getValue().getExteriorRing().equals(hole)) {
it.remove();
// if you want to exit the loop as soon as you found a match:
break;
}
}
答案 1 :(得分:3)
如何按照建议使用entrySet()迭代器。
for(Iterator<Map.Entry<Double, Ploygon>> iter = sortedPolygons.entrySet().iterator();
iter.hasNext();) {
Map.Entry<Double, Ploygon> entry = iter.next();
if (condition)
iter.remove();
}
但是,您不需要密钥,因此您可以迭代值
for(Iterator<Ploygon> iter = sortedPolygons.values().iterator();
iter.hasNext();) {
Ploygon ploygon = iter.next();
if (condition)
iter.remove();
}