Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't Enumerations Iterable?

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 to iterate over an Enumeration you must do the following:

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

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'.

like image 419
SCdF Avatar asked Aug 26 '08 01:08

SCdF


People also ask

Why is Java iterator not iterable?

As others have said, an Iterable can be called multiple times, returning a fresh Iterator on each call; an Iterator is used just once. So they are related, but serve different purposes. Frustratingly, however, the "compact for" method works only with an iterable.

What is not iterable in Java?

The JavaScript exception "is not iterable" occurs when the value which is given as the right-hand side of for...of , as argument of a function such as Promise. all or TypedArray. from , or as the right-hand side of an array destructuring assignment, is not an iterable object.

Why do we use enumerations?

Enumerations make for clearer and more readable code, particularly when meaningful names are used. The benefits of using enumerations include: Reduces errors caused by transposing or mistyping numbers. Makes it easy to change values in the future.

What is difference between enum and enumeration?

Enumeration is created by using a keyword called “enum”. Given below is the syntax with which we can create an enumeration. Note: enum can be defined only inside a top-level class or interface or in a static context. It should not be inside a method.


2 Answers

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.

like image 88
Tom Hawtin - tackline Avatar answered Sep 28 '22 08:09

Tom Hawtin - tackline


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 call iterator() on it repeatedly, creating as many Iterator instances 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. (As an aside, I noticed that Java 7's DirectoryStream violates expectations in just this way, and shouldn't be allowed to "escape" either.)

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?

like image 24
erickson Avatar answered Sep 28 '22 06:09

erickson