views:

1666

answers:

6

In Java 5 and above you have the foreach loop, which works magically on anything that implements Iterable:

for (Object o : list) {
  doStuff(o);
}

However, Enumerable still does not implement Iterable, meaning that do iterate over an Enumeration you must do the following:

for(; e.hasMoreElements() ;) {
  doStuff(e.getNextElement());
}

Does anyone know if there is a reason why Enumeration still does not implement Iterable?

Edit: As a clarification, I'm not talking about the language concept of an enum, I'm talking a Java-specific class in the Java API called 'Enumeration'.

A: 

@MDC,

Sorry, I should have been more specific. I'm talking about the Enumeration interface. Certain classes still use these and it's annoying that they cannot be used in a foreach loop.

SCdF
This answer should be a comment
finnw
Dude... it's from 2008. We didn't even *have* comments back then.
SCdF
+10  A: 

Enumeration hasn't been modified to support Iterable because it's an interface not a concrete class (like Vector, which was modifed to support the Collections interface).

If Enumeration was changed to support Iterable it would break a bunch of people's code.

Blorgbeard
Still, given that there is for-each support for **both** Iterable **and** arrays, why didn't sun include Enumerable as well?
Adrian
@Adrian Kuhn: they didn't include for-each support for Iterator, and Enumerable behaves like an Iterator, not an Iterable.
Laurence Gonsalves
+4  A: 

AFAIK Enumeration is kinda "deprecated":

Iterator takes the place of Enumeration in the Java collections framework

I hope they'll change the Servlet API with JSR 315 to use Iterator instead of Enumeration.

david
+12  A: 

It doesn't make sense for Enumeration to implement Iterable. Iterable is a factory method for Iterator. Enumeration is analogous to Iterator, and only maintains state for a single enumeration.

So, be careful trying to wrap an Enumeration as an Iterable. If someone passes me an Iterable, I will assume that I can repeatedly call iterator on it, creating as many Iterators as I want, and iterating independently on each. A wrapped Enumeration will not fulfill this contract; don't let your wrapped Enumeration escape from your own code.

Enumeration is like an Iterator, not an Iterable. A Collection is Iterable. An Iterator is not.

You can't do this:

Vector<X> list = …
Iterator<X> i = list.iterator();
for (X x : i) {
    x.doStuff();
}

So it wouldn't make sense to do this:

Vector<X> list = …
Enumeration<X> i = list.enumeration();
for (X x : i) {
    x.doStuff();
}

There is no Enumerable equivalent to Iterable. It could be added without breaking anything to work in for loops, but what would be the point? If you are able to implement this new Enumerable interface, why not just implement Iterable instead?

erickson
+6  A: 

As an easy and clean way of using an Enumeration with the enhanced for loop, convert to an ArrayList with java.util.Collections.list.

for (TableColumn col : Collections.list(columnModel.getColumns()) {

(javax.swing.table.TableColumnModel.getColumns returns Enumeration.)

Note, this may be very slightly less efficient.

Tom Hawtin - tackline
A: 

On Java Specialists Issue 107, Dr. Heinz M. Kabutz shows a nice way to make an Iterable instance from an Enumeration via adapter.

Cristofer