【问题标题】:Why aren't Enumerations Iterable?为什么枚举不是可迭代的?
【发布时间】:2010-09-06 20:02:12
【问题描述】:

在 Java 5 及更高版本中,您有 foreach 循环,它可以神奇地适用于任何实现 Iterable 的东西:

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

但是,Enumerable 仍然没有实现 Iterable,这意味着要遍历 Enumeration,您必须执行以下操作:

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

有人知道Enumeration 仍然没有实现Iterable 的原因吗?

编辑:澄清一下,我不是在谈论 enum 的语言概念,我是在谈论 Java API 中名为“Enumeration”的 Java 特定类.

【问题讨论】:

  • 不应该是块内的doStuff(e.nextElement()) 吗?

标签: java enumeration iterable


【解决方案1】:

枚举没有被修改来支持 Iterable,因为它是一个接口而不是一个具体的类(比如 Vector,它被修改为支持 Collections 接口)。

如果将 Enumeration 更改为支持 Iterable,它将破坏一堆人的代码。

【讨论】:

  • 尽管如此,既然对 both 可迭代 数组都有 for-each 支持,为什么 sun 不包括 Enumerable 呢?跨度>
  • @Adrian Kuhn:他们不包括对 Iterator 的 for-each 支持,并且 Enumerable 的行为类似于 Iterator,而不是 Iterable。
  • 枚举不是 IterABLE。 Enumeratrion 实际上是 IteraTOR(但没有“删除”)stackoverflow.com/a/8197868/117220。有了这个澄清,答案是这会破坏现有的 API。如果接口中允许部分实现(如在 Scala 特征中),则可以向后兼容地执行此操作。
  • @PetrGladkikh:但他们仍然没有在 Java 8 中修复它。
  • @JohnEye 即使在 Java 8 中使用默认方法,也不可能完全实现基于 EnumerationIterable。没有什么可以“修复”的; EnumerationIterable 在逻辑上不是等效类型,Collections.list() 中已经提供了一个转换实用程序来正确弥合它们之间的差距
【解决方案2】:

AFAIK 枚举是 kinda "deprecated":

迭代器代替 Java 集合中的枚举 框架

我希望他们将使用 JSR 315 更改 Servlet API 以使用迭代器而不是枚举。

【讨论】:

    【解决方案3】:

    Enumeration 实现 Iterable 没有意义。 IterableIterator 的工厂方法。 Enumeration 类似于 Iterator,并且只维护单个枚举的状态。

    因此,尝试将Enumeration 包装为Iterable 时要小心。如果有人给我一个Iterable,我会假设我可以重复调用iterator(),创建任意数量的Iterator 实例,并在每个实例上独立迭代。包裹的Enumeration 将不履行本合同;不要让您包装的Enumeration 从您自己的代码中逃脱。 (顺便说一句,我注意到 Java 7 的 DirectoryStream 以这种方式违反了预期,也不应该被允许“逃脱”。)

    Enumeration 类似于Iterator,而不是IterableCollectionIterableIterator 不是。

    你不能这样做:

    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();
    }
    

    没有与Iterable 等效的Enumerable。它可以在不破坏任何东西的情况下添加到 for 循环中,但有什么意义呢?如果你能够实现这个新的Enumerable 接口,为什么不直接实现Iterable 呢?

    【讨论】:

      【解决方案4】:

      作为使用具有增强 for 循环的枚举的一种简单且干净的方法,使用 java.util.Collections.list 转换为 ArrayList。

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

      (javax.swing.table.TableColumnModel.getColumns 返回枚举。)

      请注意,这可能会稍微降低效率。

      【讨论】:

      • 搞笑:这(列模型中的列)是我发现这个问题的确切原因。
      【解决方案5】:

      如果您希望它在语法上更简洁,您可以使用:

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

      【讨论】:

        猜你喜欢
        • 2020-02-04
        • 2013-09-03
        • 1970-01-01
        • 2011-02-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多