Bry*_*hen 4 java iterator concept
我正在研究java iterator接口,无法理解为什么它的设计是这样的.
为什么Java的迭代器使用hasNext,并next代替它们合并成一个方法?
这是java迭代器的典型用法
Iterator iter = //iterator from a list
while(iter.hasNext()){
Object obj = iter.next();
// do something to obj
}
Run Code Online (Sandbox Code Playgroud)
为什么不
Iterator iter = //iterator from a list
Object obj = null;
try {
while(true){
obj = iter.next();
// do something to obj
}
} catch (NoSuchElementException e) {}
Run Code Online (Sandbox Code Playgroud)
很明显,这种方法看起来很丑陋,但是如果next返回null到达end而不是抛出异常会发生什么?比代码可以简化为
Iterator iter = //iterator from a list
Object obj = null;
while((obj = iter.next()) != null){
// do something to obj
}
Run Code Online (Sandbox Code Playgroud)
这就是Objective-C中NSEnumerator的工作原理
NSEnumerator *enumerator = // from an array
while (id obj = [enumerator nextObject]) {
// do something to obj
}
Run Code Online (Sandbox Code Playgroud)
这增加了实现自定义的开销iterator.
这也使得java迭代器不是线程安全的.例如,ArrayList中包含一个元素.两个线程同时要求该列表使用相同的迭代器hasNext.两个线程都将看到,true并且它们将next在该迭代器上调用.因为只有一个元素,并且迭代器被要求两次,这肯定会导致异常或错误状态.
我知道有线程安全的迭代器,但我不确定它的实现,但我认为发生了很多阻塞,这使得它效率低下.
我认为问题是检查和更新不是原子地发生的,我无法理解为什么java设计这样的iterator界面.
更新
我看到null可以是一个值,所以我的方法是无效的.但是我上面提到的问题是否有任何可能的解决方法?
你的命题将使得null集合中的值不可能,因为它null用作"毒丸"来检测迭代的结束.
在非常罕见的情况下,两个线程共享一个迭代器,你只需要将它包装在一些自定义类中并同步对迭代器的访问,以使check-then-act操作成为原子.无论如何这都是必需的,因为即使迭代器只有一个方法,后台集合(在您的示例中为ArrayList)也不是线程安全的.
| 归档时间: |
|
| 查看次数: |
982 次 |
| 最近记录: |