/ / Ostrzeżenie FindBugs: Nieefektywne korzystanie z iteratora keySet - java, iterator, sonarqube, treemap, findbugs

Ostrzeżenie FindBugs: Nieefektywne użycie iteratora keySet - java, iterator, sonarqube, treemap, findbugs

To podobne pytanie do [Ostrzeżenie FindBugs: Nieefektywne użycie iteratora keySet zamiast iteratora entrySet

Jednak tam staram się zrobić coś nieco innego. Mój obecny kod jest tutaj:

for (Double key2 : sortedPolygons.keySet()) {
if (sortedPolygons.get(key2).getExteriorRing().equals(hole)) {
sortedPolygons.remove(key2);
break;
}
}

Wykonanie czegoś takiego jak rozwiązanie w łączu nie działa. Oto implementacja wspomnianego rozwiązania:

for(Map.Entry<Double, Polygon> entry : sortedPolygons.entrySet()) {
if (entry.getValue().getExteriorRing().equals(hole)) {
.....

Problem polega na tym, że próbuję kasować wejście. Nie ma entry.remove(). Jak mogę wymienić mój pierwszy blok kodu bez błędu FindBugs:

Nieefektywne użycie iteratora keySet zamiast iteratora entrySet ->

Ta metoda uzyskuje dostęp do wartości wpisu mapy,używając klucza, który był pobrane z iteratora keySet. Bardziej efektywne jest użycie iterator przy wpisie Ustaw mapę, aby uniknąć wyszukiwania Map.get (klucz).

Należy zauważyć, że podstawową strukturą jest TreeMapi nie można tego zmienić.

Odpowiedzi:

5 dla odpowiedzi № 1

Nie rozumiem twojego rozumowania: w pierwszym fragmencie używasz

sortedPolygons.remove(key2);

usunąć klucz. Nic nie stoi na przeszkodzie, aby zrobić to samo w drugim fragmencie:

sortedPolygons.remove(entry.getKey());

Niezależnie od tego, w jaki sposób iterujesz, doprowadzi to do ConcurrentModificationException w każdym razie, ponieważ w większości kolekcji nie można go modyfikować podczas iteracji, z wyjątkiem iteratora.

Cytat z javadoc:

Iteratory zwrócone metodą iteracyjną metodykolekcje zwrócone przez wszystkie „metody widoku kolekcji” tej klasy są odporne na awarie: jeśli mapa jest modyfikowana strukturalnie w dowolnym momencie po utworzeniu iteratora, w jakikolwiek sposób, z wyjątkiem własnej metody usuwania iteratora, iterator zwróci ConcurrentModificationException.

Więc kod powinien być:

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;
}
}

3 dla odpowiedzi № 2

Co powiesz na użycie iteratora entrySet () zgodnie z sugestią.

for(Iterator<Map.Entry<Double, Ploygon>> iter = sortedPolygons.entrySet().iterator();
iter.hasNext();) {
Map.Entry<Double, Ploygon> entry = iter.next();

if (condition)
iter.remove();
}

Jednak nie potrzebujesz klucza, aby po prostu iterować wartości

for(Iterator<Ploygon> iter = sortedPolygons.values().iterator();
iter.hasNext();) {
Ploygon ploygon = iter.next();

if (condition)
iter.remove();
}