изменение коллекции в течение итерации - PullRequest
1 голос
/ 20 февраля 2012

Изменение набора через итерацию иногда создает исключение, а иногда нет, почему?

исключение одновременной модификации

       Set<Integer> j = new HashSet<Integer>();
       j.add(23);
       j.add(45);
       j.add(64);
       int c=0;
       for(Integer k: j)
       {
         if(c++==0)
         {
             j.remove(45);
         }
       }
      System.out.println(j); // concurrent modification exception

     <hr>

 //works without exception
     Set<Integer> j = new HashSet<Integer>();
       j.add(23);
       j.add(45);
       j.add(64);
       int c=0;
    for(Integer k: j)
    {
       if(k==45)
       {
           j.remove(45);
       }
    }
    System.out.println(j);//works without exception

1 Ответ

4 голосов
/ 20 февраля 2012

Из JavaDocs для HashSet:

Итераторы, возвращаемые методом итератора этого класса, работают без сбоев: если набор изменяется в любое время после создания итератора, любым способом, кроме как через собственный метод удаления итератора, итератор генерирует исключение ConcurrentModificationException. Таким образом, перед одновременной модификацией итератор быстро и чисто дает сбой, вместо того, чтобы рисковать произвольным недетерминированным поведением в неопределенное время в будущем.

Обратите внимание, что отказоустойчивое поведение итератора не может быть гарантировано , поскольку, вообще говоря, невозможно сделать какие-либо жесткие гарантии при наличии несинхронизированной одновременной модификации. Отказоустойчивые итераторы создают исключительную ситуацию ConcurrentModificationException. Следовательно, было бы неправильно писать программу, которая зависела от этого исключения в отношении его корректности: поведение итераторов, обеспечивающее отказоустойчивость, следует использовать только для обнаружения ошибок.

(выделение мое.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...