FindBugs警告:使用keySet迭代器效率低下

时间:2014-07-07 20:31:56

标签: java iterator sonarqube treemap findbugs

这是与[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,无法更改。

2 个答案:

答案 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();
}