Если внимательно присмотреться к исходникам
ArrayList'а, можно увидеть инкрементирование переменной modCount при каждом изменении списка:class ArrayList<E> {
private var modCount = 0
fun add(element: E) {
modCount++
...
}
fun remove(element: E) {
modCount++
...
}
fun clear() {
modCount++
...
}
}Такая логика нужна для сохранения консистентности данных в случаях когда используются итераторы:
class ArrayListIterator<E> {
...
fun next(): E {
/*
modCount берется из оригинального ArrayList'а
expectModCount инициализируется при создании итератора значением modCount из оригинального ArrayList'a
*/
if (modCount != expectModCount) {
throw ConcurrentModificationException()
}
...
}
}При создании итератора списка значение
modCount сохраняется в переменную итератора expectModCount, если во время итерирования коллекции вы измените список ArrayList, переменная modCount инкрементируется и перестанет равняться переменной итератора expectModCount, в итоге следующий шаг итератора выбросит исключение ConcurrentModificationException.Таким образом при итерировании коллекции гарантируется что ваши данные случайно не изменятся обходными путями и количество неявных багов будет сведено к минимуму.
P.S. Если вам нужно менять
ArrayList во время итерирования делайте это через ListIterator, специальный итератор который умеет перемещаться в обеих направлениях и изменять список.Пишите в комментах что думаете и всем хорошего кода!