Це подібне питання до [Попередження 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();
}