Ответ 1
EDIT:
Я не заметил, что вы на самом деле не добавляли карту - вы просто меняли значение внутри записи. В этом случае решение pstanton (pre-edit 1) почти правильно, но вы должны вызывать setValue
в записи, возвращаемой итератором, вместо вызова map.put
. (Возможно, что map.put
будет работать, но я не верю, что это гарантировано - в то время как документы указывают, что entry.setValue
будет работать.)
for (Iterator<Map.Entry<String, Node>> it = map.entrySet().iterator();
it.hasNext();)
{
Map.Entry<String, Node> entry = it.next();
Node n = entry.getValue().optimize();
if(n == null)
{
it.remove();
}
else
{
entry.setValue(n);
}
}
(Обидно, что entry
не имеет метода remove
, иначе вы все равно можете использовать синтаксис расширенного цикла, делая его несколько менее неуклюжим.)
Старый ответ
(Я оставил это здесь для более общего случая, когда вы просто хотите сделать произвольные изменения.)
Нет - вы не должны ни добавлять карту, ни удалять ее напрямую. Набор, возвращаемый HashSet.keySet()
, представляет собой представление на клавиши, а не снимок.
Вы можете удалить через итератор, хотя это требует, чтобы вы использовали итератор явно, а не через расширенный цикл.
Один простой вариант - создать новый набор из оригинала:
for (String key : new HashSet<String>(map.keySet())) {
...
}
На этом этапе все в порядке, потому что вы не вносите никаких изменений в набор.
EDIT: Да, вы можете определенно удалить элементы с помощью итератора с набором ключей. Из документов для HashMap.keySet()
:
Набор поддерживает удаление элементов, который удаляет соответствующие отображение с карты через Iterator.remove, Set.remove, removeAll, saveAll и clear операции. Он не поддерживает add или addAll.
Это даже указано в самом интерфейсе Map
.
1 Я решил отредактировать свой ответ, а не просто комментировать псантон, поскольку я решил, что дополнительная информация, которую я получил для подобных ситуаций, но была достаточно полезной, чтобы заслужить этот ответ.