Этот аналогичный вопрос для [ FindBugs warning: Неэффективное использование итератора keySet вместо itStation 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. Эффективнее использовать итератор на entrySet карты, чтобы избежать поиска Map.get(key).
Следует отметить, что базовая структура - TreeMap
, и ее нельзя изменить.
Я не понимаю ваших рассуждений: в первом фрагменте вы используете
sortedPolygons.remove(key2);
для удаления ключа. Ничто не мешает вам сделать то же самое во втором фрагменте:
sortedPolygons.remove(entry.getKey());
Независимо от того, как вы итерации, это приведет к ConcurrentModificationException
любом случае, потому что для большинства коллекций вы не можете изменять его во время итерации на нем, за исключением использования его итератора.
Цитата из javadoc:
Итераторы, возвращаемые методом итератора коллекций, возвращаемых всеми этими методами "методы просмотра коллекции", являются неустойчивыми: если карта структурно модифицирована в любое время после создания итератора, любым способом, кроме как через собственный итератор, удалить метод, итератор будет вызывать исключение 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;
}
}
Как насчет того, как вы используете итератор 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();
}