почему iterator.remove () был описан как необязательная операция? - PullRequest
9 голосов
/ 08 октября 2009

Я просмотрел документацию (http://java.sun.com/javase/6/docs/api/java/util/Iterator.html) из Iterator.remove() там remove() был описан как

void remove()

Удаляет из базовой коллекции последний возвращенный элемент. итератором (необязательная операция). Этот метод может быть вызван только один раз за звонок на следующий. Поведение итератор не указан, если базовая коллекция изменена в то время как итерация в процессе любым другим способом, кроме как позвонив по этому способ.

  1. Так может кто-нибудь сказать, что означает «необязательный».
  2. Влияет ли это на надежность работы? (Как и в случае с ++, это не гарантирует надежность операций.)
  3. Почему "опционально" было указано здесь категорически.
  4. Что означает «модификация» во второй строке документации

поведение итератора не определено, если базовая коллекция модифицирована

Ответы [ 3 ]

13 голосов
/ 08 октября 2009

# 1: Необязательно означает, что вы можете реализовать его или бросить UnsupportedOperationException

# 2: эта операция необязательна, потому что иногда вы просто не хотите, чтобы содержимое вашего итератора изменялось. Или что вы понимаете под "надежностью работы"?

РЕДАКТИРОВАТЬ # 4: behavior of an iterator is unspecified if the underlying collection is modified

Обычно вы используете итератор, выполняя

List<String> c = new ArrayList<String>();
c.add("Item 1");
c.add("Item 2");
c.add("Item 3");
...
for (Iterator<String> i = c.iterator(); i.hasNext();)
{
  String s = i.next();
  ...
}

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

c.remove("Item 2");

это не чисто , возможно искажает данные в вашем Списке / Коллекции / ... и его следует избегать . Вместо этого удалите () элемент через итератор :

i.remove();
6 голосов
/ 08 октября 2009

Прежде всего java.util.Iterator - это интерфейс, то есть соглашение о том, как классы, реализующие этот интерфейс, взаимодействуют с остальным миром. Они несут ответственность за то, как они будут реализовывать методы interface.

Если базовая структура данных не допускает удаления, тогда remove() выдаст UnsupportedOperationException. Например, если вы перебираете набор результатов, извлеченный из БД, имеет смысл не реализовывать этот метод.

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

2 голосов
/ 08 октября 2009

Он описывается как необязательный, поскольку не все классы коллекций, которые могут предоставить вам итератор, реализуют метод remove() в возвращаемом ими итераторе. Если возвращенный итератор не реализует его, будет выброшено UnsupportedOperationException.

Обычные java.util.ArrayList, java.util.LinkedList и другие стандартные классы коллекций реализуют метод remove() в своих итераторах, поэтому вы можете безопасно его использовать.

...