Fast-fail-исключение происходит только при добавлении элемента, а не при удалении
Fast-Fail : это означает, что, если они обнаруживают
что коллекция изменилась с момента начала итерации, они бросают непроверенный
ConcurrentModificationException
.
я написал тестовый пример demonsterate это:
String hi = "Hi";
list.add(hi);
list.add("Buy");
System.out.println("list before: " + list);
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
list.add("Good");
}
выход:
list before: [Hi, Buy]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at thread.CollectionTest.main(CollectionTest.java:19)
, который ожидается. Однако при удалении элемента исключение не создается:
List<String> list = new ArrayList<>();
String hi = "Hi";
list.add(hi);
list.add("Buy");
System.out.println("list before: " + list);
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String string = iterator.next();
list.remove(hi);
}
выход:
list before: [Hi, Buy]
list after: [Buy]
почему это? в обоих случаях список изменяется.
2 ответов
дело в том, что это не hasNext()
Это проверяет на модификацию, но next()
. В сценарии "удалить" вы подавляете next
вызов, который будет бросать, потому что нет следующего элемента.
если у вас было 3 элемента в начале, удаление одного приведет к hasNext
быть "истинным". Затем следующее next
выдаст ожидаемое исключение.
JavaDoc указывает, что функциональность "fail-fast" работает на основе "лучших усилий" и что она должна быть используется только для обнаружения ошибок, а не действительно зависит от него, чтобы программа вела себя правильно. Очевидно, из-за таких побочных эффектов.
ConcurrentModificationException
будет бросать, вы можете внести некоторые изменения в список во время итерации.
после выполнения модификации в списке во время итерации, если вы пытаетесь получить доступ к следующему() или удалить () с помощью итератора, то он проверяет modCount и expectedModCount и count не то же самое, то он бросает ConcurrentModificationException
.
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}