0

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

boolean hasNextCalled = false;

boolean hasNext() {
  hasNextCalled  = true
}

next() {
  assert hasNextCalled
}

这样一来,我们就永远不会遇到 NoSuchElementException() 的情况。没有强制执行 hasNext() 调用的任何实际原因?

4

6 回答 6

9

会有什么好处?您只是将 a 替换为 a NoSuchElementExceptionAssertionError并引入了一点点开销。此外,由于Iterator是接口,因此您无法实现一次;它必须在Iterator. 另外,文档并没有强制要求在调用hasNext之前调用next,因此您的提议会违反当前的合同。这样的更改会破坏任何依赖于NoSuchElementException. 最后,可以在生产代码中关闭断言,因此您仍然需要该NoSuchElementException机制。

于 2013-08-15T22:14:43.813 回答
3

NoSuchElementException是一个运行时异常,并反映了程序员的错误......就像你的方法一样。调用不是强制性的,hasNext()因为也许您不需要——例如,您提前知道集合的大小,并且知道next()可以调用多少次。

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

于 2013-08-15T22:15:12.140 回答
1

也许我们已经知道还有元素。例如,也许我们正在以锁步方式迭代两个大小相同的列表,而我们只需要调用hasNext一个迭代器来检查两者。此外,调用实际上并不能阻止任何人在没有assert的情况下hasNext调用,尤其是在断言关闭的情况下。nexthasNext

于 2013-08-15T22:18:56.880 回答
1

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

于 2013-08-15T22:20:46.413 回答
0

首先,您建议的断言只会在启用断言时运行。

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

其他海报也给出了很好的理由(正如我正在输入的那样),特别是 Iterator 是一个接口,并且有许多实现。

于 2013-08-15T22:21:40.183 回答
0

我的 2 美分。在这里,API 对客户端的使用做出假设并强制执行。假设我总是确定我只返回 1 个结果,那么最好绕过hasNext()调用并通过调用直接检索元素next()

于 2013-08-15T22:15:54.053 回答