/ / Попередження FindBugs: неефективне використання ітератора keySet - java, ітератор, sonarqube, treemap, findbugs

Попередження FindBugs: Неефективне використання ітератора keySet - java, iterator, sonarqube, treemap, findbugs

Це подібне питання до [Попередження FindBugs: Неефективне використання ітератора keySet замість ітератора entrySet

Однак там я намагаюся зробити щось дещо інше. Мій поточний код тут:

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

Цей метод отримує доступ до значення запису на карті,за допомогою ключа, який був отримано з ітератора keySet. Більш ефективно використовувати iterator on entrySet на карті, щоб уникнути пошуку Map.get (ключ).

Зазначимо, що основна структура така TreeMap, і його неможливо змінити.

Відповіді:

5 за відповідь № 1

Я не розумію ваших міркувань: у першому фрагменті ви використовуєте

sortedPolygons.remove(key2);

щоб вийняти ключ. Ніщо не заважає зробити те саме у другому фрагменті:

sortedPolygons.remove(entry.getKey());

Яким би способом ви не повторювались, це призведе до ConcurrentModificationException у будь-якому випадку, оскільки для більшості колекцій ви не можете змінити його під час ітерації, крім використання його ітератора.

Цитата з явадок:

Ітератори, повернуті методом ітераторів зколекції, що повертаються всіма "методами перегляду колекції" цього класу, є швидкодіючими: якщо карта структурно модифікована в будь-який час після створення ітератора, будь-яким способом, крім власного методу видалення ітератора, ітератор викине 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;
}
}

3 для відповіді № 2

Як щодо того, щоб використовувати ітератор 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();
}