Java 为什么迭代器不执行hasnext调用?

Java 为什么迭代器不执行hasnext调用?,java,iterator,Java,Iterator,如果hasNext和Next是这样工作的,那么这似乎是一个很好的方法: boolean hasNextCalled = false; boolean hasNext() { hasNextCalled = true } next() { assert hasNextCalled } 这样,我们就永远不会在没有接触过lementException()的情况下着陆。 没有强制执行hasNext()调用的任何实际原因 有什么好处?您只需将一个NoTouchElementExceptio

如果hasNext和Next是这样工作的,那么这似乎是一个很好的方法:

boolean hasNextCalled = false;

boolean hasNext() {
  hasNextCalled  = true
}

next() {
  assert hasNextCalled
}
这样,我们就永远不会在没有接触过lementException()的情况下着陆。
没有强制执行hasNext()调用的任何实际原因

有什么好处?您只需将一个
NoTouchElementException
替换为一个
AssertionError
,外加一点开销。另外,因为迭代器是一个接口,所以您不能一次实现它;它必须包含在
迭代器的每个实现中。另外,文档没有要求在调用
next
之前调用
hasNext
,因此您的提案将破坏当前合同。这样的更改将破坏任何依赖于
NoTouchElementException
编写的代码。最后,可以在生产代码中关闭断言,因此您仍然需要
NoSuchElementException
机制。

NoSuchElementException
是一个运行时异常,反映程序员错误……与您的方法完全相同。调用
hasNext()
不是必须的,因为您可能不需要这样做——例如,您事先知道集合的大小,并且知道可以调用多少个
next()


关键是,您正在将一种报告程序员错误的方法替换为另一种报告程序员错误的方法,这种方法可以禁用一些有用的方法。

我的2美分。在这里,API对客户机的使用做出了一个假设,并强制这样做。假设我总是确信我只返回一个结果,那么最好通过调用
hasNext()
直接检索元素,只调用
next()
也许我们已经知道还有元素。例如,我们可能在lockstep中迭代两个大小相同的列表,我们只需要在一个迭代器上调用
hasNext
,即可检查这两个列表。另外,
assert
调用
hasNext
实际上并不会阻止任何人在没有
hasNext
的情况下调用
next
,尤其是在断言关闭的情况下。

您可能知道有一个
next()
,例如,如果您总是有成对的元素,一个对
hasNext()的调用
将允许两次调用
next()

首先,您建议的断言仅在启用断言时运行

但是主要的问题是你只考虑一个用例。该库旨在以最小的限制支持程序员的工作,并且每个类和方法都必须适合于一个内聚和连贯的整体

其他海报也给出了很好的理由(正如我键入的),特别是迭代器是一个接口,并且有许多实现