为什么Iterable <e>和Iterator <e>在不同的包中?</e> </e>

时间:2011-08-02 01:02:44

标签: java iterator iterable

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结构。

5 个答案:

答案 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.*子包已经开发出各种循环依赖关系。例如,

  1. java.lang.Process - java.io
  2. java.lang.Readable - java.io,java.nio
  3. java.lang.String - java.util
  4. java.lang.System - java.io,java.nio,java.util
  5. 所以我认为最好不要将子包视为一种明确分层依赖关系的机制。相反,子包组相关的专门行为(全能util除外)和lang选择性地引入一些非常有用的结构,如IteratorLocale。< / 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];
    ...
}

(当然,我们也无法直接访问ai。)

顺便说一句,编译器没有 import java.util.Iterator - 在编译的字节码中,每个类型都以其全名引用。 (并且局部变量实际上并不是真正的类型 - 对于某些checkcast断言也是如此。)