我想知道为什么Iterator.next()会抛出NoSuchElementException。通常,如果使用迭代器,您将执行以下操作:
for(MyClass o: myFancyObject) {
o.doSomething();
}
将编译为
Iterator it = myFancyObject.iterator();
while(it.hasNext()) {
MyClass o = (MyClass)(iterator.next());
o.doSomething();
}
但是为什么next()方法抛出NoSuchElementException?
因此,让我们在next()方法中调用hasNext()方法,如下所示:
public MyClass next() {
if (! hasNext())
throw new NoSuchElementException();
return mySecretDataModel.getElement(counter++);
}
但后来我发现了以下问题:hasNext()方法将在每次迭代中被调用两次。首先,它是从使用迭代器的方法调用的,然后是next()方法的第二次调用。这需要不必要的计算时间。是这个意图还是只是Iterator界面的作者的设计监督?
答案 0 :(得分:1)
iterator
可能由于某些原因而抛出NoSuchElementException,但最明显的是调用者没有调用hasNext()
或忽略结果。
答案 1 :(得分:0)
你会这样写的
public MyClass next() {
if (counter >= mySecretDataModel.getSize())
throw new NoSuchElementException();
return mySecretDataModel.getElement(counter++);
}
答案 2 :(得分:0)
我认为不需要致电hasNext()
,更好的方法是:
public MyClass next() {
if (counter >= mySecretDataModel.size())
throw new NoSuchElementException();
return mySecretDataModel.getElement(counter++);
}
另一个选择是你在MyObject nextElement
期间计算的字段中存储你的迭代器状态,它是一对boolean hasNext
和hasNext()
,因此没有两次调用。
答案 3 :(得分:0)
你在两个陈述中都是完全正确的。第一个(尽管这里有所有其他答案)是我们应该从hasNext()
调用next()
,以避免代码重复。第二个是调用hasNext()
两次是不必要的操作,计算成本。
由于defensive,我们正在hasNext()
对next()
进行此次调用。我们可以跳过此操作,让next()
假设hasNext()
已经被调用,我们的客户知道他在做什么。但这可能会导致意外和不可预测的异常,例如NullPointerException
。
所以,这里的答案是 - defensive programming是好事,即使它花费了一些东西。