Iterable<E>
位于java.lang
,而Iterator<E>
位于java.util
。这有充分的理由还是仅仅是一个糟糕设计的神器?
这似乎有点奇怪,因为Iterable<E>
唯一有益的是提供Iterator<E>
。
编辑:一个可能的原因是因为(then-)新引入的for-each循环。我想我的问题是,它们是否相同?
for(Object o : collection)
...
vs
for( Iterator iter = collection.iterator(); iter.hasNext(); ) {
o = iter.next();
...
如果是,那么仍然无法解释为什么这两个类在不同的包中,因为编译器必须导入java.util
才能使用Iterator
结构。
答案 0 :(得分:9)
部分内容是历史记录:Iterator
一直伴随着我们 JDK 1.2 ,而Iterable
来自 JDK 1.5 。 Iterable
带来了增强的for
循环。
糟糕的设计?不,进化。没有全知的创造者。随着经验的学习,它们被整合到JDK中。
答案 1 :(得分:8)
java.lang
保留用于语言功能依赖项的类。 Iterable
直接通过for-each循环支持语言级别,但Iterator
没有。
答案 2 :(得分:5)
大多数集合实现Iterable
,以便您可以使用方便的for循环语法:
Iterable<T> someIterableThing;
for (T x : someIterableThing) { ... }
我认为Iterable
位于java.lang
中,因为它与此语法密切相关,这是Java语言的一个特性。
答案 3 :(得分:2)
随着时间的推移,Java的java.*
子包已经开发出各种循环依赖关系。例如,
所以我认为最好不要将子包视为一种明确分层依赖关系的机制。相反,子包组相关的专门行为(全能util
除外)和lang
选择性地引入一些非常有用的结构,如Iterator
和Locale
。< / p>
我猜一个人也可以将它全部归结为熵。
答案 4 :(得分:2)
回答其他问题:
增强的for循环有两种变体。其中之一,当
中的collection
参数时
for(E o : collection) {
...
}
是实现Iterable<E>
的东西,完全等同于
for (Iterator<E> iter = collection.iterator(); iter.hasNext(); ) {
E o = iter.next();
...
}
(区别在于Iterator没有可以在循环的其余部分访问的变量名)。编译器将为每个版本生成非常相似甚至完全相同的代码。
增强型for
循环还有另一种变体:当collection
是一个数组时,它会被编译成这样的东西:
E[] a = collection;
for(int i = 0; i < a.length; i++) {
E o = a[i];
...
}
(当然,我们也无法直接访问a
或i
。)
顺便说一句,编译器没有 import java.util.Iterator
- 在编译的字节码中,每个类型都以其全名引用。 (并且局部变量实际上并不是真正的类型 - 对于某些checkcast
断言也是如此。)