Коллекция-Итератор.remove() vs Collection.удалить()


Согласно Солнцу,

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

У меня есть два вопроса:

  1. что делает эту операцию " итератором.remove () " стабильнее, чем остальные ?
  2. почему они предоставили " коллекцию.удалить ()" метод, если он не будет полезен в большинстве примеры использования?
6 8

6 ответов:

Если вы перебираете коллекцию и используете:

Collection.remove() 

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

Если вы используете:

Iterator.remove()

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

Прежде всего, Collection.remove() очень полезно. Он применим во многих случаях использования, вероятно, в большей степени, чем Iterator.remove().

Однако последний решает одну специфическую проблему: он позволяет изменять коллекцию , повторяя ее.

Задача, решаемая с помощью Iterator.remove(), иллюстрируется ниже:

    List<Integer> l = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4));
    for (int el : l) {
        if (el < 3) {
            l.remove(el);
        }
    }

Этот код является недопустимым, так как l.remove() вызывается во время итерации над l.

Правильно написать его следующим образом:

    Iterator<Integer> it = l.iterator();
    while (it.hasNext()) {
        int el = it.next();
        if (el < 3) {
            it.remove();
        }
    }

Как ясно сказано в приведенной вами документации,

Итератор.удалить-единственный безопасный способ изменить коллекцию во время итерации

(курсив добавлен)

При использовании итератора am вы не можете изменить коллекцию, кроме как вызвав Iterator.remove().

Если вы не повторяете коллекцию, вы бы использовали Collection.remove().

Что делает эту операцию " итератором.remove () " стабильнее, чем остальные ?

Это означает, что итератор знает, что вы удалили элемент, поэтому он не будет производить ConcurrentModifcationException.

Почему они предоставили " коллекцию.метод remove()" если он не будет полезен в большинстве случаев использования ?

Обычно вы используете карту.remove() или Collection.remove (), так как это может быть намного эффективнее, чем перебор всех объектов. Если вы удаляете часто повторяясь, я подозреваю, что вы должны использовать разные коллекции.

  1. Это просто дизайнерский выбор. Можно было бы указать другое поведение (т. е. итератор должен пропускать значения, которые были удалены коллекцией.remove ()), но это значительно усложнило бы реализацию фреймворка сбора данных. Так что выбор оставить его неопределенным.

  2. Это очень полезно. Если вы знаете объект, который хотите удалить, зачем повторять?

Насколько я понимаю, коллекция.remove (int index) также вернет удаленный объект. Повторяющийся.удалить () не получится.