2008-08-26 7 views
57

En Java 5 o superior que tiene el bucle foreach, que funciona mágicamente en cualquier cosa que implementa Iterable:¿Por qué las enumeraciones no se pueden modificar?

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

Sin embargo, Enumerable todavía no implementa Iterable, lo que significa que para iterar sobre una Enumeration debe hacer lo siguiente :

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

¿alguien sabe si hay una razón por la Enumeration todavía no implementa Iterable?

Editar: Como aclaración, no estoy hablando sobre el concepto de un lenguaje enum, estoy hablando de una clase Java-específico en la API de Java llamada 'Enumeration'.

+0

¿No debería ser hacerTarea (e.nextElement()) dentro del bloque? –

Respuesta

34

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 de Colecciones).

Si se modificó la enumeración para admitir Iterable, se rompería un montón de código de las personas.

+11

Aún así, dado que hay soporte para cada una de las matrices ** ambas ** Iterables ** y **, ¿por qué Sun no incluyó a Enumerable también? – akuhn

+8

@Adrian Kuhn: no incluyeron para cada soporte para Iterator, y Enumerable se comporta como un iterador, no como un Iterable. –

+4

La enumeración no es IteraBLE. Enumeratrion es en realidad IteraTOR (pero sin 'eliminar') http://stackoverflow.com/a/8197868/117220. Con esta aclaración, la respuesta es que esto rompería las API existentes. Sería posible hacer esto al revés-compatible si se permite la implementación parcial en Interfaces (como en los rasgos de Scala). –

6

yo sepa enumeración es kinda "deprecated":

iterador toma el lugar de Enumeración de las colecciones de Java marco

espero que vayan a cambiar la API Servlet con JSR 315 para utilizar en lugar de iterador de la enumeración.

44

No tiene sentido que Enumeration implemente Iterable. Iterable es un método de fábrica para Iterator. Enumeration es análogo a Iterator, y solo mantiene el estado para una sola enumeración.

Por lo tanto, tenga cuidado al intentar envolver Enumeration como Iterable. Si alguien me pasa un Iterable, asumiré que puedo llamar al iterator() en él repetidamente, creando tantas instancias Iterator como desee, e iterando de forma independiente en cada una. Un envuelto Enumeration no cumplirá este contrato; no permita que su envuelto Enumeration escape de su propio código. (Dicho sea de paso, me di cuenta de que de Java 7 DirectoryStream viola las expectativas justamente de esta manera, y no se debe permitir que "escapar" tampoco.)

Enumeration es como un Iterator, no un Iterable. A Collection es Iterable. Un Iterator no lo es.

No se puede hacer esto:

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

lo tanto, 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, pero ¿cuál sería el punto? Si puede implementar esta nueva interfaz Enumerable, ¿por qué no implementar simplemente Iterable?

72

Como una forma fácil y limpia de forma de utilizar una enumeración con el bucle for mejorado, conviértalo en una ArrayList con java.util.Collections.list.

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

(javax.swing.table.TableColumnModel.getColumns devuelve Enumeración.)

Nota, esto puede ser muy ligeramente menos eficiente.

+2

Divertido: esto (columnas en el modelo de columna) es la razón exacta Encontré esta pregunta. – Dave

+0

Buena solución. –

1

Si simplemente desea que sea sintácticamente un poco más limpio, puede utilizar:

while(e.hasMoreElements()) { 
    doStuff(e.nextElement()); 
} 
Cuestiones relacionadas