为什么枚举不可迭代?
在Java 5及更高版本中,我们具有foreach循环,该循环可神奇地实现实现Iterable的任何事物:
for (Object o : list) { doStuff(o); }
但是,Enumerable
仍然没有实现Iterable
,这意味着要对Enumeration
进行迭代,我们必须执行以下操作:
for(; e.hasMoreElements() ;) { doStuff(e.nextElement()); }
有谁知道Enumeration
仍然不实现Iterable
的原因吗?
编辑:为澄清起见,我不是在谈论枚举的语言概念,而是在Java API中称为"枚举"的Java特定类。
解决方案
回答
枚举没有被修改为支持Iterable,因为它是一个接口,而不是一个具体的类(例如Vector,它被修改为支持Collections接口)。
如果将Enumeration更改为支持Iterable,则会破坏很多人的代码。
回答
AFAIK枚举有点"不建议使用":
Iterator takes the place of Enumeration in the Java collections framework
我希望他们使用JSR 315将Servlet API更改为使用Iterator而不是Enumeration。
回答
"枚举"实现"可迭代"是没有意义的。 "可迭代"是"迭代器"的工厂方法。 "枚举"类似于"迭代器",并且仅维护单个枚举的状态。
因此,请小心尝试将"枚举"包装为"可迭代"。如果有人给我传递了一个"可迭代的",我将假定可以重复调用" iterator()",并根据需要创建任意数量的" Iterator"实例,并在每个实例上进行独立迭代。包装好的"枚举"将无法履行此合同;不要让我们包装的"枚举"从我们自己的代码中转义。 (顺便说一句,我注意到Java 7的DirectoryStream
违反了这种期望,也不应该允许它"转义"。)
"枚举"就像是"迭代器",而不是"可迭代"。 "集合"是"可迭代的"。 Iterator
不是。
我们不能这样做:
Vector<X> list = … Iterator<X> i = list.iterator(); for (X x : i) { x.doStuff(); }
因此,这样做是没有意义的:
Vector<X> list = … Enumeration<X> i = list.enumeration(); for (X x : i) { x.doStuff(); }
没有等效于"可迭代"的"可枚举"。可以添加它而无需中断for循环中的任何工作,但是这样做有什么意义呢?如果我们能够实现这个新的" Enumerable"接口,为什么不仅仅实现" Iterable"呢?
回答
作为将枚举与增强的for循环结合使用的简便方法,请使用java.util.Collections.list转换为ArrayList。
for (TableColumn col : Collections.list(columnModel.getColumns()) {
(javax.swing.table.TableColumnModel.getColumns返回枚举。)
请注意,这可能会稍微降低效率。