java迭代器背后的概念是什么?

java迭代器背后的概念是什么?,java,iterator,concept,Java,Iterator,Concept,我正在研究java迭代器接口,不明白为什么它会这样设计 为什么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 Obje

我正在研究java
迭代器
接口,不明白为什么它会这样设计

为什么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 *enumerator = // from an array
while (id obj = [enumerator nextObject]) {
    // do something to obj
}

这增加了实现自定义
迭代器的开销

这也使得java迭代器不是线程安全的。例如,ArrayList中有一个元素。两个线程都同时为该列表请求相同的迭代器
hasNext
。然后两个线程都将看到
true
,并在该迭代器上调用
next
。因为只有一个元素,迭代器被询问了两次,这肯定会导致异常或错误状态

我知道有线程安全迭代器,但我不确定它是否实现得很好,但我认为很多阻塞正在发生,这使得它效率低下

我认为问题在于检查和更新并不是原子化的,我不理解java为什么要设计这样的
iterator
接口


更新


我看到null可以是一个值,所以我的方法是无效的。但是,对于我上面提到的问题,有什么可能的解决方法吗?

您的建议将使集合中不可能有
null
值,因为它使用
null
作为“毒丸”来检测迭代的结束


在非常罕见的情况下,两个线程共享一个迭代器,您只需将其封装在某个自定义类中,并同步对迭代器的访问,以使检查然后执行原子操作。无论如何都需要这样做,因为即使迭代器只有一个方法,支持集合(在您的示例中为ArrayList)也不是线程安全的。

您的第一个建议是糟糕的设计,因为它依赖于为已知最终会发生的情况引发和捕获异常。例外是相当昂贵的,并且只适用于通常不应该发生的“例外”情况

您的第二个建议没有考虑到
Iterable
s可以有空元素


至于线程安全位,是的,标准
迭代器
s往往不是线程安全的,因此需要增加开销的自定义实现。大多数Java结构都是这样。正如所说,更重要的是
Iterable
结构在其
迭代器
可用之前是线程安全的。

为了提高源代码的清晰度,请使用(例如字符串集合)

Iterable值=…//通常是一个集合(列表、集合…)
for(字符串值:值){
//做一些有价值的事情
}
我同意之前关于空有界集合、带异常的循环控制(这是一种糟糕的形式)和线程安全的回答


在您的建议中,将集合设为null边界是最不明智的,尤其是当您的代码中有“no nulls”策略时。然而,它是非常单一的Java(编辑:并破坏了迭代器接口的契约),因此很容易混淆代码的未来维护者(编辑:并可能导致微妙和/或意外的错误)。

。。我从没想过空值可以被放入列表中。。。我太习惯于以客观C+1的方式思考,但我会添加第二个简短的句子,说明原因。有两种状态,然后使
next()
返回null:null值或不再返回元素。要解决这个问题,您必须禁止将
null
作为值。@FabianBarney禁止将null作为值可能不是个坏主意,请注意。我仍然不会用它来表示Java
迭代器的结束:它破坏了契约。@Andrews Pencer我同意在项目中限制
null
的使用是有意义的。然而,在像collections
null
这样的易受攻击的环境中,IMHO确实是有意义的,不应该被普遍禁止。想想存储在集合中的数据库结果等。您是否担心源代码的清晰性,或者担心调用
hasNext()
然后调用
next()
的性能成本?我正在做一个与java迭代器相关的大学课程项目,所以只想了解更多关于itOk的信息。在现实世界中,源代码的清晰性几乎总是比微小的性能调整更重要的问题。在额外方法调用的成本开始成为执行时间的重要因素之前,您必须执行大量循环。
Iterable<String> values = ... // typically a Collection (List, Set...)

for (String value : values) {
    // do something with the value
}