Нет - при первом выполнении вашего условия вы получите ConcurrentModificationException
на следующей итерации.
В целом, небезопасно изменять коллекцию напрямую при ее итерации, и в этой ситуации итераторы «отказоустойчивы» (поскольку в целом, когда они могут обнаруживать изменения, нет общий способ разобраться, как с ними справиться).
В этой ситуации одна идиома, которая работает, - это использовать собственный метод Итератора remove()
. Удаление элемента таким контролируемым образом держит итератор в курсе того, что происходит, и имеет согласованную семантику того, что должно происходить с порядком итерации, и поэтому работает так, как вы ожидаете:
Iterator<Object> iter = set.iterator();
while (iter.hasNext()) {
final Object o = iter.next();
if (some_condition) {
iter.remove();
}
}
Обратите внимание, что remove()
является «необязательной операцией», и не все итераторы коллекций поддерживают ее. Если вы застряли в этой ситуации, альтернативой, которая всегда будет работать, является получение копии набора, итерации по , и удаление объектов из оригинального набора, например, так :
Set<Object> copy = new HashSet<Object>(set);
for (Object o: copy) {
if (some_condition) {
set.remove(o);
}
}
Поскольку итерация завершена copy
, в то время как изменения происходят с set
, одновременных изменений не происходит, и итератор доволен.