¿Por qué las enumeraciones no son iterables?
-
09-06-2019 - |
Pregunta
En Java 5 y superiores tienes el bucle foreach, que funciona mágicamente en cualquier cosa que implemente Iterable
:
for (Object o : list) {
doStuff(o);
}
Sin embargo, Enumerable
todavía no implementa Iterable
, lo que significa que para iterar sobre un Enumeration
debes hacer lo siguiente:
for(; e.hasMoreElements() ;) {
doStuff(e.nextElement());
}
¿Alguien sabe si hay una razón por la cual Enumeration
todavía no implementa Iterable
?
Editar: Como aclaración, no me refiero al concepto lingüístico de un enumeración, estoy hablando de una clase específica de Java en la API de Java llamada 'Enumeración'.
Solución
La enumeración no se ha modificado para admitir Iterable porque es una interfaz, no una clase concreta (como Vector, que se modificó para admitir la interfaz Colecciones).
Si se cambiara Enumeration para admitir Iterable, se rompería el código de un montón de personas.
Otros consejos
Como una manera fácil y limpio forma de utilizar una enumeración con el bucle for mejorado, convertirla a una ArrayList con java.util.Collections.list.
for (TableColumn col : Collections.list(columnModel.getColumns()) {
(javax.swing.table.TableColumnModel.getColumns devuelve Enumeración).
Tenga en cuenta que esto puede ser un poco menos eficiente.
No tiene sentido para Enumeration
para implementar Iterable
. Iterable
es un método de fábrica para Iterator
. Enumeration
es análogo a Iterator
, y solo mantiene el estado para una única enumeración.
Así que tenga cuidado al intentar envolver un Enumeration
como un Iterable
.Si alguien me pasa un Iterable
, asumiré que puedo llamar iterator()
en él repetidamente, creando tantas Iterator
instancias como quiero, e iterando de forma independiente en cada una.un envuelto Enumeration
no cumplirá este contrato;no dejes que tu envuelto Enumeration
escapar de tu propio código.(Aparte, noté que Java 7 DirectoryStream
viola las expectativas precisamente de esta manera, y tampoco se le debería permitir "escapar".)
Enumeration
es como un Iterator
, no un Iterable
.A Collection
es Iterable
.Un Iterator
no es.
No puedes hacer esto:
Vector<X> list = …
Iterator<X> i = list.iterator();
for (X x : i) {
x.doStuff();
}
Entonces no tendría sentido hacer esto:
Vector<X> list = …
Enumeration<X> i = list.enumeration();
for (X x : i) {
x.doStuff();
}
No hay Enumerable
equivalente a Iterable
.Se podría agregar sin romper nada para trabajar en bucles for, pero ¿cuál sería el punto?Si eres capaz de implementar esta nueva Enumerable
interfaz, ¿por qué no simplemente implementar Iterable
¿en cambio?
La enumeración AFAIK es un poco "obsoleto":
Iterator toma el lugar de la enumeración en el marco de las colecciones Java
Espero que cambien la API de Servlet con JSR 315 para usar Iterator en lugar de Enumeration.
Si simplemente desea que sea un poco más limpio sintácticamente, puede usar:
while(e.hasMoreElements()) {
doStuff(e.nextElement());
}