如果 hasNext 和 Next 像这样工作,这似乎是一个很好的方法:
boolean hasNextCalled = false;
boolean hasNext() {
hasNextCalled = true
}
next() {
assert hasNextCalled
}
这样一来,我们就永远不会遇到 NoSuchElementException() 的情况。没有强制执行 hasNext() 调用的任何实际原因?
会有什么好处?您只是将 a 替换为 a NoSuchElementException
,AssertionError
并引入了一点点开销。此外,由于Iterator
是接口,因此您无法实现一次;它必须在Iterator
. 另外,文档并没有强制要求在调用hasNext
之前调用next
,因此您的提议会违反当前的合同。这样的更改会破坏任何依赖于NoSuchElementException
. 最后,可以在生产代码中关闭断言,因此您仍然需要该NoSuchElementException
机制。
NoSuchElementException
是一个运行时异常,并反映了程序员的错误......就像你的方法一样。调用不是强制性的,hasNext()
因为也许您不需要——例如,您提前知道集合的大小,并且知道next()
可以调用多少次。
关键是您正在将一种报告程序员错误的方式换成……另一种报告程序员错误的方式,这种方式可以禁用一些有用的方法。
也许我们已经知道还有元素。例如,也许我们正在以锁步方式迭代两个大小相同的列表,而我们只需要调用hasNext
一个迭代器来检查两者。此外,调用实际上并不能阻止任何人在没有assert
的情况下hasNext
调用,尤其是在断言关闭的情况下。next
hasNext
你可能知道有一个next()
,例如,如果你总是有一对元素,一次调用hasNext()
将允许两次调用next()
。
首先,您建议的断言只会在启用断言时运行。
但主要问题是您只考虑一个用例。该库旨在以最小的限制支持程序员的工作,并且每个类和方法都必须适合一个有凝聚力和连贯的整体。
其他海报也给出了很好的理由(正如我正在输入的那样),特别是 Iterator 是一个接口,并且有许多实现。
我的 2 美分。在这里,API 对客户端的使用做出假设并强制执行。假设我总是确定我只返回 1 个结果,那么最好绕过hasNext()
调用并通过调用直接检索元素next()