Подтвердить что ты не робот

Java Modcount (ArrayList)

В Eclipse я вижу, что объекты ArrayList имеют поле modCount. В чем его цель? (количество модификаций?)

4b9b3361

Ответ 1

Это позволяет внутренним компонентам списка знать, была ли сделана структурная модификация, которая может привести к тому, что текущая операция даст неверные результаты.

Если вы когда-либо получали ConcurrentModificationException из-за изменения списка (например, удаления элемента) во время его итерации, его внутренний modCount был тем, что отключилось от итератора.

AbstractList docs дают хорошее подробное описание.

Ответ 2

Да. Если вы когда-либо намереваетесь расширить AbstractList, вы должны написать свой код, чтобы он придерживался modCount javadoc, как указано ниже:

/**
 * The number of times this list has been <i>structurally modified</i>.
 * Structural modifications are those that change the size of the
 * list, or otherwise perturb it in such a fashion that iterations in
 * progress may yield incorrect results.
 *
 * <p>This field is used by the iterator and list iterator implementation
 * returned by the {@code iterator} and {@code listIterator} methods.
 * If the value of this field changes unexpectedly, the iterator (or list
 * iterator) will throw a {@code ConcurrentModificationException} in
 * response to the {@code next}, {@code remove}, {@code previous},
 * {@code set} or {@code add} operations.  This provides
 * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
 * the face of concurrent modification during iteration.
 *
 * <p><b>Use of this field by subclasses is optional.</b> If a subclass
 * wishes to provide fail-fast iterators (and list iterators), then it
 * merely has to increment this field in its {@code add(int, E)} and
 * {@code remove(int)} methods (and any other methods that it overrides
 * that result in structural modifications to the list).  A single call to
 * {@code add(int, E)} or {@code remove(int)} must add no more than
 * one to this field, or the iterators (and list iterators) will throw
 * bogus {@code ConcurrentModificationExceptions}.  If an implementation
 * does not wish to provide fail-fast iterators, this field may be
 * ignored.
 */

Взглянув на фактический исходный код JDK и прочитав javadocs (онлайн или в коде), очень помогите понять, что происходит. Удачи.

Я бы добавил, вы можете добавить исходный код JDK в Eclipse, чтобы каждый F3 или CTRL + щелчок по любому классу/методу Java SE указывал на фактический исходный код. Если вы загружаете JDK, у вас должен быть src.zip в установочной папке JDK. Теперь в Eclipse в верхнем меню перейдите в окно "Настройки" Java "Установленные JRE. Выберите текущую JRE и нажмите" Изменить ". Выберите файл rt.jar, щелкните ссылку" Источник ", щелкните" Внешний файл", перейдите в папку JDK, выберите файл src.zip и добавьте его. Теперь исходный код Java SE API доступен в Eclipse. Исходный код JDK дает много идей. Счастливое кодирование:)

Ответ 3

Это количество изменений структуры (размера) коллекции

Ответ 4

protected transient int modCount = 0;
- это свойство, объявленное в public abstract class AbstractList,
для определения общего количества структурных изменений, сделанных в этой коллекции.

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

Это будет полезно бросить ConcurrentModificationException.
ConcurrentModificationException будет выбрано при повторении коллекции одним потоком, и в коллекции будет изменен другой поток. Это достигается, как и всякий раз, когда создается объект итератора. ModCount будет установлен в expectedCount, и каждая итераторная перспектива ожидается с помощью modCount, чтобы сбросить ConcurrentModificationException при изменении.

private class Itr implements Iterator<E> {
    ...
    ...
    /**
     * The modCount value that the iterator believes that the backing
     * List should have.  If this expectation is violated, the iterator
     * has detected concurrent modification.
     */
    int expectedModCount = modCount;

    public E next() {
        checkForComodification();
    ...
    ...
    }

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

}

size() api здесь не подходит; поскольку, если есть две операции (добавление и удаление), которые произошли до того, как следующий(), называемый неподвижным размером, отобразит одно и то же значение; следовательно, не удалось обнаружить изменения, произошедшие в этой коллекции, используя size() api во время итерации. Следовательно, нам нужна модификация_increment_counter, которая modCount.

Ответ 5

Из Java API для поля числа мод:

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

Ответ 6

Из 1.4 javadoc в AbstractList:

protected transient int modCount

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

Это поле используется итератором и верна реализация итератора списка с помощью итератора и listIterator методы. Если значение этого поля неожиданно изменяется, итератор (или list iterator), будет ConcurrentModificationException в ответ на следующий, удалить, предыдущие, установленные или добавленные операции. Эта обеспечивает быстродействующее поведение, скорее чем недетерминированное поведение в лицом одновременной модификации во время итерации.

Использование этого поля по подклассам является необязательным.