Por que as enumerações não são iteráveis?
-
09-06-2019 - |
Pergunta
No Java 5 e superior você tem o loop foreach, que funciona magicamente em qualquer coisa que implemente Iterable
:
for (Object o : list) {
doStuff(o);
}
No entanto, Enumerable
ainda não implementa Iterable
, o que significa que para iterar sobre um Enumeration
você deve fazer o seguinte:
for(; e.hasMoreElements() ;) {
doStuff(e.nextElement());
}
Alguém sabe se há uma razão pela qual Enumeration
ainda não implementa Iterable
?
Editar: A título de esclarecimento, não estou falando do conceito de linguagem de um enumeração, estou falando de uma classe específica de Java na API Java chamada 'Enumeração'.
Solução
A enumeração não foi modificada para suportar Iterable porque é uma interface e não uma classe concreta (como Vector, que foi modificada para suportar a interface Collections).
Se Enumeration fosse alterado para suportar Iterable, isso quebraria o código de muitas pessoas.
Outras dicas
Como é fácil e limpar maneira de usar uma Enumeração com o loop for aprimorado, converta para um ArrayList com java.util.Collections.list.
for (TableColumn col : Collections.list(columnModel.getColumns()) {
(javax.swing.table.TableColumnModel.getColumns retorna Enumeração.)
Observe que isso pode ser um pouco menos eficiente.
Não faz sentido para Enumeration
implementar Iterable
. Iterable
é um método de fábrica para Iterator
. Enumeration
é análogo a Iterator
, e mantém o estado apenas para uma única enumeração.
Portanto, tome cuidado ao tentar embrulhar um Enumeration
como um Iterable
.Se alguém me passar um Iterable
, presumo que posso ligar iterator()
nele repetidamente, criando tantos Iterator
instâncias como eu quiser e iterando independentemente em cada uma.Um embrulhado Enumeration
não cumprirá este contrato;não deixe seu embrulhado Enumeration
escapar do seu próprio código.(Além disso, notei que o Java 7 DirectoryStream
viola as expectativas exatamente dessa maneira e também não deveria ser permitido “escapar”.)
Enumeration
é como um Iterator
, não um Iterable
.A Collection
é Iterable
.Um Iterator
não é.
Você não pode fazer isso:
Vector<X> list = …
Iterator<X> i = list.iterator();
for (X x : i) {
x.doStuff();
}
Portanto, não faria sentido fazer isso:
Vector<X> list = …
Enumeration<X> i = list.enumeration();
for (X x : i) {
x.doStuff();
}
Não há Enumerable
equivalente a Iterable
.Ele poderia ser adicionado sem quebrar nada para funcionar em loops for, mas qual seria o sentido?Se você for capaz de implementar este novo Enumerable
interface, por que não apenas implementar Iterable
em vez de?
A enumeração AFAIK é meio "obsoleto":
O iterador substitui o lugar de enumeração na estrutura de coleções Java
Espero que eles mudem a API do Servlet com JSR 315 para usar o Iterator em vez da Enumeração.
Se você quiser que seja sintaticamente um pouco mais limpo, você pode usar:
while(e.hasMoreElements()) {
doStuff(e.nextElement());
}