РЕДАКТИРОВАТЬ: В этом ответе я пытался утверждать, что это разрешено, о чем спрашивает вопрос. Но я пропустил одно предложение в Iterator.hasNext
документации, которое лишает законной силы все мои рассуждения:
Другими словами, возвращает true, если next()
вернет элемент, а не вызовет исключение.
Кажется, это означает, что повторный вызов next
до тех пор, пока hasNext
не вернет true, а вызов next до получения NoSuchElementException
должен вернуть ту же последовательность элементов.
Таким образом, кажется, что вопрос о том, что не разрешено.
Оригинальный ответ
Это попытка указать специалиста юриста типа ответа. Для ясности я переформулирую вопрос в компактной форме:
Разрешено ли в спецификации Iterable
выдавать NoSuchElementException
, когда Iterator.next
вызывается без предшествующего вызова Iterator.hasNext
, даже если бы элемент был возвращен, если бы Iterator.hasNext
был вызван первым? 1030 *
Обсуждение
Документация для Iterator.hasNext
гласит:
Возвращает true, если в итерации больше элементов.
А для Iterator.next
:
Броски: NoSuchElementException
- если в итерации больше нет элементов
По-видимому, разрешено генерировать NoSuchElementException
, когда "в итерации больше нет элементов", но не раньше. Это должно совпадать с тем, когда hasNext
возвращает false.
Это приводит к вопросу: что конкретно означает документация с «итерацией» и «элементами»? Документация Iterator
не дает ответа на этот вопрос, что дает некоторую возможность для разработчиков.
На мой взгляд, есть две возможные интерпретации:
С точки зрения самого интерфейса итератора единственное существующее понятие «итерации» - «до тех пор, пока hasNext
возвращает истину». Это означает, что если клиент вызывает next
до hasNext
, он не знает, есть ли еще элементы, он не определен.
Следовательно, согласно спецификации для разработчика итератора можно решить, что итерация завершена. Так что ответ на вопрос - да.
Но в документации по Iterable.iterator
также упоминаются "элементы":
Возвращает итератор для элементов типа T
.
Так что же здесь означает "элементы"? Означает ли это «все элементы в коллекции, реализующие Iterable
? Нет, это не так, и не все итерируемые, даже имеют фиксированный набор элементов.
Что означают "элементы" для некоторой конкретной итерации, остается решать разработчику. Допустимое определение «элементов» для итератора может быть « все элементы в коллекции, ИЛИ, все элементы до того, как клиент решит вызвать next
до hasNext
».
Так что этот случай также приводит к выводу, что ответ на вопрос - да. (Но, пожалуйста, смотрите примечание в конце!)
Conclution
Документация не совсем ясна, но кажется, что ответ на вопрос: да, это разрешено.
Примечание
В случае, если итератор делает то, что спрашивает об этом поведении, он, конечно, должен быть задокументирован. Но другие итерируемые объекты также должны документировать, над какими элементами находятся их итераторы.
Например, в документации ArrayList.iterator
четко указано , на каких элементах закончился итератор:
Возвращает итератор для элементов в этом списке в правильной последовательности.
Последнее замечание: Да, я сумасшедший, чтобы тратить на это так много времени.