【发布时间】:2012-03-20 19:06:16
【问题描述】:
我正在研究javaiterator接口,不明白为什么会这样设计。
为什么java迭代器使用hasNext和next而不是将它们合并成一个方法?
这是java迭代器的典型用法
Iterator iter = //iterator from a list
while(iter.hasNext()){
Object obj = iter.next();
// do something to obj
}
为什么不
Iterator iter = //iterator from a list
Object obj = null;
try {
while(true){
obj = iter.next();
// do something to obj
}
} catch (NoSuchElementException e) {}
很明显,这种方法看起来很难看,但是如果next 在到达结束时返回 null 而不是抛出异常会发生什么?比代码可以简化为
Iterator iter = //iterator from a list
Object obj = null;
while((obj = iter.next()) != null){
// do something to obj
}
这就是 Objective-C 中 NSEnumerator 的工作原理
NSEnumerator *enumerator = // from an array
while (id obj = [enumerator nextObject]) {
// do something to obj
}
这增加了实现自定义iterator的开销。
这也使得 java 迭代器不是线程安全的。例如,一个 ArrayList 中有一个元素。两个线程同时要求该列表hasNext 的相同迭代器。两个线程都将看到true,它们将在该迭代器上调用next。因为只有一个元素,并且迭代器被询问了两次,这肯定会导致异常或错误状态。
我知道有线程安全的迭代器,但我不确定它是否能实现,但我认为很多阻塞正在发生,这使得它效率低下。
我认为问题是检查和更新不是自动发生的,我不明白为什么 java 设计了这样的iterator 接口。
更新
我看到 null 可以是一个值,所以我的方法是无效的。但是我上面提到的问题有什么可能的解决方法吗?
【问题讨论】:
-
您是担心源代码的清晰度,还是担心调用
hasNext()然后next()的性能成本? -
我正在做一个与 Java 迭代器相关的大学课程项目,所以只想了解更多信息
-
好的。在现实世界中,源代码的清晰度几乎总是比微小的性能调整更令人担忧。在额外方法调用的成本开始成为执行时间的重要因素之前,您必须执行 糟糕 很多循环。