ConcurrentModificationException с вектором и clear () - PullRequest
3 голосов
/ 18 мая 2011

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

vector v = new Vector();
v.add(1);
v.add(2);
v.add(3);
ListIterator iter = v.listIterator();

while (iter.hasNext()) {
    System.out.println(iter.next());
}

v.clear()

Но я получаю исключение ConcurrentModificationException.

Из прочтения этого вопроса, видимо, использование "синхронизированного" в некотором роде является решением. Но я вижу пару разных подходов, и мне интересно, каков наилучший и самый простой способ решить эту проблему в моем случае (без участия явных потоков)?

Ответы [ 2 ]

6 голосов
/ 18 мая 2011

Если никакие потоки не задействованы, вероятно, приведенный вами пример неполон.

Это ConcurrentModificationException может произойти просто, если вы измените коллекцию во время итерации по ней.

Обратите внимание, что это исключение не всегда указывает на то, что объект был одновременно изменен другим потоком.Если один поток выдает последовательность вызовов методов, которая нарушает контракт объекта, объект может вызвать это исключение.Например, если поток изменяет коллекцию напрямую, в то время как он выполняет итерацию по коллекции с помощью итератора, работающего без сбоев, итератор отбросит это исключение.

И документы для Vector.listIterator() явно заявляют, что:

Обратите внимание, что итератор списка, возвращаемый этой реализацией, будет генерировать исключение UnsupportedOperationException в ответ на его методы удаления, установки и добавления, если в списке не удалены (int), set (int, Object) и не добавленыМетоды (int, Object) переопределяются.

(На самом деле, документы для AbstractList.listIterator(int); Vector не переопределяют это.)

2 голосов
/ 18 мая 2011

Позвольте мне сократить этот код для вас:

Vector<Integer> v = new Vector<Integer>();
v.add(1);
v.add(2);
v.add(3);
for (Integer i: v) {
    System.out.println(i);
}
v.clear();

Вы не должны использовать listIterator(), если не выполняете навигацию вперед и назад.Для простой итерации используйте метод iterator(), предпочтительно в стиле для каждого, который я показал выше (где фактический объект итератора скрыт от вас).

И не используйте Vector !!!Вместо этого используйте ArrayList.

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