Pourquoi je ne peux pas le faire :
Enumeration e = ...
for (Object o : e)
...
Pourquoi je ne peux pas le faire :
Enumeration e = ...
for (Object o : e)
...
Parce que Enumeration<T>
ne s'étend pas Iterable<T>
. Voici un exemple de réalisation d'énumérations itérables .
Quant à savoir pourquoi, c'est une question intéressante. Ce n'est pas exactement votre question mais cela l'éclaire un peu. De la FAQ sur la conception de l'API Java Collections :
Pourquoi Iterator n'étend-il pas Enumeration ?
Nous considérons les noms de méthodes pour Enumeration comme malheureux. Ils sont très longs, et très fréquemment utilisés. Étant donné que nous avons ajouté une méthode et créer un tout nouveau cadre, nous avons pensé qu'il serait stupide de ne pas de ne pas profiter de l'occasion pour d'améliorer les noms. Bien sûr, nous pourrions supporter les nouveaux et anciens noms dans Iterator, mais cela ne semble pas intéressant.
Cela me laisse penser que Sun veut prendre ses distances par rapport à Enumeration, qui est un des premiers Java avec une syntaxe assez verbeuse.
Question suivante : pourquoi les énumérations ne sont-elles pas itérables ? stackoverflow.com/questions/27240/
Y a-t-il une différence sémantique entre les deux ? (Je ne suis pas familier avec la classe Iterable) ? Pourquoi ne pas travailler également sur l'énumération ?
Parce que les énumérations sont plus proches des Iterator, et non des Iterable (voir la question que mmyers a postée sur stackoverflow). Comme solution de contournement, vous pouvez faire for(; e.hasMoreElements(); ) { e.getNextElement(); }
En utilisant la classe utilitaire Collections, l'énumération peut être rendue itérable comme suit :
Enumeration headerValues=request.getHeaders("mycustomheader");
List headerValuesList=Collections.list(headerValues);
for(Object headerValueObj:headerValuesList){
... do whatever you want to do with headerValueObj
}
Les éléments sont copiés dans une nouvelle liste avant de commencer l'itération, cette solution doit être évitée pour les longues énumérations. Les solutions transformant une énumération en un itérateur ont moins d'impact sur la mémoire.
J'ai résolu ce problème avec deux classes très simples, une pour Enumeration
et un pour Iterator
. Le wrapper d'énumération est le suivant :
static class IterableEnumeration<T>
extends Object
implements Iterable<T>, Iterator<T>
{
private final Enumeration<T> enumeration;
private boolean used=false;
IterableEnumeration(final Enumeration<T> enm) {
enumeration=enm;
}
public Iterator<T> iterator() {
if(used) { throw new IllegalStateException("Cannot use iterator from asIterable wrapper more than once"); }
used=true;
return this;
}
public boolean hasNext() { return enumeration.hasMoreElements(); }
public T next() { return enumeration.nextElement(); }
public void remove() { throw new UnsupportedOperationException("Cannot remove elements from AsIterator wrapper around Enumeration"); }
}
qui peut être utilisé soit avec une méthode utilitaire statique (ce qui est ma préférence) :
/**
* Convert an `Enumeration<T>` to an `Iterable<T>` for a once-off use in an enhanced for loop.
*/
static public <T> Iterable<T> asIterable(final Enumeration<T> enm) {
return new IterableEnumeration<T>(enm);
}
...
for(String val: Util.asIterable(enm)) {
...
}
ou en instanciant la classe :
for(String val: new IterableEnumeration<String>(enm)) {
...
}
Le nouveau style de boucle-for ("foreach") fonctionne sur les tableaux, et les éléments qui implémentent la fonction Iterable
interface.
C'est aussi plus analogue à Iterator
que de Iterable
Il n'y aurait donc pas de sens à ce que Enumeration
pour travailler avec foreach sauf si Iterator
l'a fait aussi (et ce n'est pas le cas). Enumeration
est également déconseillé en faveur de Iterator
.
Enumeration
ne met pas en œuvre Iterable
et en tant que tel, il ne peut pas être utilisé directement dans une boucle foreach. Cependant, en utilisant Collections Apache Commons il est possible d'itérer sur une énumération avec :
for (Object o : new IteratorIterable(new EnumerationIterator(e))) {
...
}
Vous pouvez également utiliser une syntaxe plus courte avec Collections.list()
mais cette méthode est moins efficace (deux itérations sur les éléments et plus de mémoire utilisée) :
for (Object o : Collections.list(e))) {
...
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
4 votes
L'énumération a été remplacée par l'Iterator dans Java 1.2 en 1998 et est conservée pour des raisons d'héritage. La vraie question est de savoir pourquoi vous voulez l'utiliser. Peut-être parce que vous utilisez une bibliothèque qui vous oblige à le faire ?
2 votes
@Peter - oui, une bibliothèque externe est la solution.