Pourquoi les énumérations ne sont-elles pas itérables ?
-
09-06-2019 - |
Question
Dans Java 5 et versions ultérieures, vous disposez de la boucle foreach, qui fonctionne comme par magie sur tout ce qui implémente Iterable
:
for (Object o : list) {
doStuff(o);
}
Cependant, Enumerable
ne met toujours pas en œuvre Iterable
, ce qui signifie que parcourir un Enumeration
vous devez faire ce qui suit :
for(; e.hasMoreElements() ;) {
doStuff(e.nextElement());
}
Est-ce que quelqu'un sait s'il y a une raison à cela Enumeration
ne met toujours pas en œuvre Iterable
?
Modifier: Pour précision, je ne parle pas du concept linguistique d'un énumération, je parle d'une classe spécifique à Java dans l'API Java appelée 'Énumération'.
La solution
L'énumération n'a pas été modifiée pour prendre en charge Iterable car il s'agit d'une interface et non d'une classe concrète (comme Vector, qui a été modifié pour prendre en charge l'interface Collections).
Si l'énumération était modifiée pour prendre en charge Iterable, cela briserait le code de nombreuses personnes.
Autres conseils
Comme une solution facile et faire le ménage façon d'utiliser une énumération avec la boucle for améliorée, convertissez-la en ArrayList avec java.util.Collections.list.
for (TableColumn col : Collections.list(columnModel.getColumns()) {
(javax.swing.table.TableColumnModel.getColumns renvoie l'énumération.)
Notez que cela peut être très légèrement moins efficace.
Cela n'a pas de sens pour Enumeration
implémenter Iterable
. Iterable
est une méthode d'usine pour Iterator
. Enumeration
est analogue à Iterator
, et ne conserve l'état que pour une seule énumération.
Alors, soyez prudent en essayant d'emballer un Enumeration
comme un Iterable
.Si quelqu'un me passe un Iterable
, je suppose que je peux appeler iterator()
dessus à plusieurs reprises, créant autant Iterator
instances comme je le souhaite, et itérer indépendamment sur chacune.Un enveloppé Enumeration
ne remplira pas ce contrat ;ne te laisse pas envelopper Enumeration
échappez-vous à votre propre code.(En passant, j'ai remarqué que Java 7 DirectoryStream
viole les attentes de cette manière et ne devrait pas non plus être autorisé à "s'échapper".)
Enumeration
est comme un Iterator
, pas un Iterable
.UN Collection
est Iterable
.Un Iterator
n'est pas.
Vous ne pouvez pas faire ceci :
Vector<X> list = …
Iterator<X> i = list.iterator();
for (X x : i) {
x.doStuff();
}
Cela n'aurait donc aucun sens de faire ceci :
Vector<X> list = …
Enumeration<X> i = list.enumeration();
for (X x : i) {
x.doStuff();
}
Il n'y a pas Enumerable
équivalent à Iterable
.Il pourrait être ajouté sans rien casser pour travailler avec des boucles for, mais à quoi cela servirait-il ?Si vous êtes en mesure de mettre en œuvre ce nouveau Enumerable
interface, pourquoi ne pas simplement implémenter Iterable
plutôt?
L'énumération AFAIK est un peu "obsolète":
Iterator remplace l'énumération dans le cadre des collections Java
J'espère qu'ils modifieront l'API Servlet avec JSR 315 pour utiliser Iterator au lieu d'Enumeration.
Si vous souhaitez simplement que ce soit syntaxiquement un peu plus propre, vous pouvez utiliser :
while(e.hasMoreElements()) {
doStuff(e.nextElement());
}