“Бесконечный” итератор, плохо разрабатывают? [закрытый]

66
задан Adamski 5 August 2010 в 16:42
поделиться

10 ответов

Я думаю, что это полностью законно - Итератор - это просто поток "материала". Почему поток обязательно должен быть ограничен?

Многие другие языки (например, Scala) имеют встроенную концепцию неограниченных потоков, и их можно повторять. Например, использование scalaz

scala> val fibs = (0, 1).iterate[Stream](t2 => t2._2 -> (t2._1 + t2._2)).map(_._1).iterator
fibs: Iterator[Int] = non-empty iterator

scala> fibs.take(10).mkString(", ") //first 10 fibonnacci numbers
res0: String = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

EDIT: С точки зрения принципа наименьшего удивления, я думаю, это полностью зависит от контекста. Например, что я могу ожидать от этого метода?

public Iterator<Integer> fibonacciSequence();
76
ответ дан 24 November 2019 в 14:59
поделиться

Вся суть Итератора в том, что он ленив, то есть дает вам столько объектов, сколько вы просите. Если пользователь запрашивает все объекты бесконечного Итератора , это его проблема, а не ваша.

19
ответ дан 24 November 2019 в 14:59
поделиться

Да. Вам просто нужны разные критерии, когда следует прекратить итерацию.

Концепция бесконечных списков очень распространена в языках ленивых вычислений, таких как Haskell, и приводит к совершенно иному дизайну программ.

4
ответ дан 24 November 2019 в 14:59
поделиться

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

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

1
ответ дан 24 November 2019 в 14:59
поделиться

Подумайте, есть ли у вас функция-генератор. Итератор может быть разумным интерфейсом для генератора, а может и не быть, как вы заметили.

С другой стороны, в Python есть генераторы, которые do завершаются.

2
ответ дан 24 November 2019 в 14:59
поделиться

Бесконечный итератор очень полезен при создании бесконечных данных, например, линейных повторяющихся последовательностей, таких как последовательность Фибоначчи.

Поэтому совершенно нормально использовать такие итераторы.

4
ответ дан 24 November 2019 в 14:59
поделиться

Хотя я тоже считаю, что это законно, я хотел бы добавить, что такой Iterator (точнее: Iterable , создающий такой Iterator ), не будет хорошо работать с расширенным циклом for (он же for-each-loop):

for (Object o : myIterable) {
   ...
}

Поскольку код внутри расширенного цикла for не имеет прямого доступа в итератор, он не может вызвать remove () на итераторе.

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

  • Получить доступ к внутреннему List итератора и удалить объекты напрямую, что может вызвать ConcurrentModificationException
  • используйте break для выхода из цикла
  • «используйте» Exception для выхода из цикла
  • используйте return для выхода the loop

Все альтернативы, кроме последней, не совсем лучший способ оставить расширенный цикл for.

"Обычный" цикл for (или любой другой цикл вместе с явной переменной Iterator ), конечно, будет работать нормально:

for (Iterator it = getIterator(); it.hasNext();) {
  Object o = it.next()
  ...
}
7
ответ дан 24 November 2019 в 14:59
поделиться

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

Тем не менее, в чем разница между бесконечностью и коллекцией из 10 триллионов предметов? Звонящий либо хочет их всех, либо не хочет. Позвольте вызывающему абоненту решить, сколько элементов вернуть или когда закончить.

Я бы не сказал, что вызывающий не может использовать конструкцию for-each. Он мог бы, пока ему нужны были все предметы.

Что-то в документации к коллекции, например «может быть бесконечная коллекция», было бы подходящим, но не «бесконечный итератор».

7
ответ дан 24 November 2019 в 14:59
поделиться

Это совершенно законное использование - при условии, что это должным образом задокументировано .

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

4
ответ дан 24 November 2019 в 14:59
поделиться

Фактически, Итератор происходит от Iterable , не a Collection , независимо от JavaDoc API говорит. Последний расширяет первый, и поэтому он может также генерировать Iterator , но вполне разумно, чтобы Iterable не был Collection . Фактически, есть даже несколько классов Java, которые реализуют Iterable , но не Collection .

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

3
ответ дан 24 November 2019 в 14:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: