11

Iterable<E>java.langIterator<E>java.util。这是否有充分的理由,或者这仅仅是糟糕设计的产物?

这似乎很奇怪,因为唯一有用的Iterable<E>是提供一个Iterator<E>.

编辑:一个潜在的原因是因为(当时)新引入的 for-each 循环。我想我的问题是,它们是等价的吗?

for(Object o : collection)
    ...
vs
for( Iterator iter = collection.iterator(); iter.hasNext(); ) {
    o = iter.next();
    ...

如果它们是,那么这仍然不能解释为什么这两个类在不同的包中,因为编译器无论如何都必须导入java.util才能使用该Iterator构造。

4

5 回答 5

11

Part of it is history: Iterator has been with us since JDK 1.2, and Iterable came with JDK 1.5. Iterable came in with the enhanced for loop.

Bad design? No, evolution. There's no all-knowing creator. As lessons are learned they're incorporated into the JDK.

于 2011-08-02T01:14:46.633 回答
8

java.lang保留给作为语言特性依赖项的类。 Iterable直接通过 for-each 循环获得语言级别的支持,但Iterator没有。

于 2011-08-02T01:06:01.050 回答
5

大多数集合都实现Iterable了,以便您可以使用方便的 for 循环语法:

Iterable<T> someIterableThing;
for (T x : someIterableThing) { ... }

我想这Iterablejava.lang因为它与这种语法密切相关,这是 Java 语言的一个特性。

于 2011-08-02T01:06:55.907 回答
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

所以我认为最好不要将子包视为一种明确分层依赖关系的机制。相反,子包分组相关的、专门的行为(除了 catch-all util),并lang有选择地引入一些非常有用的结构,如IteratorLocale

我想人们也可以把这一切都归结为熵。

于 2011-08-02T02:57:24.407 回答
2

要回答附加问题:

增强的 for 循环有两种变体。其中之一,当collection争论在

for(E o : collection) {
    ...
}

是实现的东西Iterable<E>,完全等同于

for (Iterator<E> iter = collection.iterator(); iter.hasNext(); ) {
    E o = iter.next();
    ...
}

(不同的是,迭代器没有您可以在循环的其余部分中访问的变量名)。编译器将为每个版本生成非常相似甚至完全相同的代码。

增强循环还有另一种变体for:当collection是一个数组时,它会被编译成这样的:

E[] a = collection;
for(int i = 0; i < a.length; i++) {
    E o = a[i];
    ...
}

(当然,这里我们也不能直接访问aor i。)

顺便说一句,编译器不导入 java.util.Iterator- 在编译的字节码中,每种类型都由其全名引用。(无论如何,局部变量并没有真正输入 - 其他一些checkcast断言。)

于 2011-08-02T13:07:21.377 回答