开发者

Why are Iterable<E> and Iterator<E> in different packages?

开发者 https://www.devze.com 2023-03-25 09:30 出处:网络
Iterable<E> is in java.lang whereas Iterator<E> is in java.util. Is there a good reason for this or is this merely an artifact of bad design?

Iterable<E> is in java.lang whereas Iterator<E> is in java.util. Is there a good reason for this or is this merely an artifact of bad design?

It seems strange since the only thing that an Iterable<E> is good for is providing an Iterator<E>.

EDIT: One potential reason is because of the (then-)newly introduced for-each loop. I guess my question then would be, are they equivalent?

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

If they are, then that still doesn't explain why the two classes are in different packages since the compiler would have to import java.util anyways to use the Iterator construc开发者_运维知识库t.


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.


java.lang is reserved for classes which are dependencies for language features. Iterable has language level support directly via the for-each loop but Iterator does not.


Most of the collections implement Iterable so that you can use the convenient for loop syntax:

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

I would imagine that Iterable is in java.lang because it's strongly related to this syntax, a feature of the Java language.


Over time, Java's java.* subpackages have developed various circular dependencies. For example,

  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

So I think it is best to not think about subpackages as a mechanism to clearly layer dependencies. Rather, the subpackages group related, specialized behavior (except for the catch-all util), and lang selectively pulls in some very useful constructs like Iterator and Locale.

I guess one could also chalk it all up to entropy.


To answer the additional question:

The enhanced for loop has two variants. One of them, when the collection argument in

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

is something which implements Iterable<E>, is exactly equivalent to

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

(with the difference that the Iterator has no variable name that you can access in the rest of the loop). The compiler will generate quite similar or even exactly the same code for each version.

There is another variant of the enhanced for loop: when the collection is an array, it will get compiled to something like this:

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

(Of course, here we can't directly access a or i, too.)

By the way, the compiler does not import java.util.Iterator - in the compiled bytecode, each type is referred to by its full name. (And local variables are not really typed, anyway - other for some checkcast assertions.)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号