Будет ли исключение одновременной модификации при использовании классического цикла for? - PullRequest
0 голосов
/ 27 февраля 2019

Существует ли вероятность получения исключения одновременной модификации при использовании классического цикла for?

import java.util.*;

class IterTest{
    public static void main(String[] args){
        List<Integer> nums = new ArrayList<>();
        nums.add(18);
        nums.add(1);
        nums.add(14);
        nums.add(13);
        System.out.println("Nums ->"+nums);
        int len = nums.size();
        for(int index=0;index < len ;index++){          
            System.out.println(" Current >>"+nums.get(index));
            System.out.println(" Removing >>"+nums.remove(index));          
        }
    }
}

Ответы [ 3 ]

0 голосов
/ 27 февраля 2019

Нет, этот код не даст ConcurrentModificationException.Это исключение обычно возникает, когда представление коллекции «испорчено» из-за того, что коллекция из-под нее исключена.Типичными примерами этого являются изменение коллекции во время ее итерации с помощью Iterator (которая неявно используется в инструкции для расширенного использования) или получение subList(), изменение базового списка и последующее использование подсписка.

Однако этот код будет работать в том же состоянии, которое «портит» цикл, за исключением того, что будет выдано другое исключение.Границы цикла основаны на начальном размере списка.Однако тело цикла удаляет элементы из списка, поэтому код в конечном итоге будет индексироваться за пределами списка, что приведет к IndexOutOfBoundsException.

. Как исправить этот код, зависит от того, что вы пытаетесь сделать,Первоначально может показаться разумным избегать ConcurrentModificationException, используя списочные индексы вместо Iterator.Однако, если список структурно изменен (то есть элементы добавлены или удалены) во время цикла, необходимо тщательно отрегулировать границы индекса и цикла, в противном случае элементы могут быть пропущены, продублированы или может возникнуть IndexOutOfBoundsException.

0 голосов
/ 24 марта 2019

Нет, как предлагали другие ответы, ConcurrentModificationException не будет встречаться в данном коде.

Так, когда возникает исключение ConcurrentModificationException?

В однопоточной среде это обычно происходит, когда выиспользуйте Iterators, чтобы перебрать коллекцию и изменить ее одновременно.

Почему?

Если вы проверяете исходный код реализаций Iterator, он всегда выполняет checkForComodification () всякий раз, когда вы используете какой-либо метод итератора (например,далее (), удалить ()).Например, код для этого метода в ArrayList.java:

final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

, где modCount - статическая переменная, поддерживаемая на уровне класса ArrayList, которая указывает, сколько раз этот список был структурномодифицирована.И ожидаемое количество модификаций pectedModCount поддерживается на уровне класса Iterator, который изначально равен modCount.

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

Поскольку в вашем случае вы не использовали ничего из этого, проверки на Co-модификацию не будет, и, следовательно, вы не получите ConcurrentModificationException.

Примечание.: Как указано в в этом ответе , вы получите IndexOutOfBoundsException, так как вы проверили index < len в цикле for и len инициализируется до начального размера массива.Простое решение этого было бы:

 for(int index=0;index < nums.size;index++)
0 голосов
/ 27 февраля 2019

Нет, шансов нет.При использовании итераторов может возникнуть исключение одновременной модификации, см. Что такое отказоустойчивые и отказоустойчивые итераторы в java

...