【问题标题】:Difference between Java Enumeration and IteratorJava枚举和迭代器的区别
【发布时间】:2010-10-31 04:43:17
【问题描述】:

这两个接口之间的确切区别是什么? Enumeration 是否比使用 Iterator 有好处?如果有人可以详细说明,将不胜感激参考文章。

【问题讨论】:

标签: java collections iterator enumeration


【解决方案1】:

查看Iterator接口的Java API Specification,有对Enumeration的区别的解释:

迭代器不同于 枚举有两种方式:

  • 迭代器允许调用者从底层移除元素 在迭代期间收集 定义明确的语义。
  • 方法名称已得到改进。

底线是,EnumerationIterator 都会给出连续的元素,但Iterator 通过缩短措辞改进了方法名称,并且它还有一个额外的remove 方法。这是一个并排的比较:

  Enumeration                     Iterator
  ----------------                ----------------
  hasMoreElements()               hasNext()
  nextElement()                   next()
  N/A                             remove()

正如 Java API 规范中也提到的,对于较新的程序,Iterator 应该优先于 Enumeration,因为“迭代器在 Java 集合框架中取代了枚举”。 (来自Iterator 规范。)

【讨论】:

  • 我认为这个答案中缺少一些关于并发性的解释。
  • @Paul_Draper:编辑不应该为帖子添加新的含义,这就是 cmets 的用途。
  • @coobird 你确定“枚举通常更快”吗?因为枚举具有“在 nextElement() 中同步代码块”并且我们在迭代器处没有同步,这会导致 ConcurrentModificationException rit??我们是否称迭代器通常更快,而枚举更安全一些。 ??
  • @KanagaveluSugumar 感谢您指出这一点。 (我没有注意到这个答案中添加了额外的讨论。)我已经回滚了编辑,因为它并不完全准确。
  • "方法名称已改进。" - 感谢您的诚实;)
【解决方案2】:

迭代器是 fail-fast 。即,当一个线程通过添加/删除操作更改集合,而另一个线程使用 hasNext() or next() 方法通过迭代器遍历它时,迭代器通过抛出 ConcurrentModificationException 快速失败。迭代器的快速失败行为只能用于检测错误。 Hashtable、Vector 等类的方法返回的枚举不是快速失败的,这是通过同步 nextElement() 方法中的代码块来实现的,该方法会锁定当前的 Vector 对象,这会花费大量时间。

【讨论】:

  • 只有部分正确:此行为未在接口中定义,取决于迭代器的实现。确实,java.util 中的“旧”集合实现(HashSet、ArrayList 等)表现出这种行为。但是,较新的“并发”集合永远不会抛出 ConcurrentModificationException,它们将在迭代器创建时遍历集合。其他实现可能仍会表现出不同的行为。
  • 另外值得指出的是:“请注意,不能保证快速失败的行为,因为一般来说,在存在不同步的并发修改的情况下不可能做出任何硬保证。快速失败的操作会抛出 ConcurrentModificationException尽最大努力。因此,编写一个依赖此异常来确保其正确性的程序是错误的:ConcurrentModificationException 应该只用于检测错误。 docs.oracle.com/javase/7/docs/api/java/util/…
【解决方案3】:

“正式”,它们应该与支持额外操作(例如,删除)的迭代器接口相似。通常,倾向于使用迭代器。

这里来自the enumeration interface javadocs

注意:此接口的功能与 迭代器接口。此外, 迭代器添加一个可选的删除 操作,并且有更短的方法 名字。新的实现应该 考虑优先使用迭代器 枚举。

【讨论】:

    【解决方案4】:

    一个简单的事实,但在之前的答案中没有提到,Iterator<T>Iterable<T> 一起用于解释 for(_type_ element:collection){...} 结构。

    【讨论】:

      【解决方案5】:

      枚举和迭代器有基本的三个区别

      枚举
      1. 仅用于 lagacy 类(例如Vector

          Enumeration e = v.elements();  
          v is the object of `Vector` class
      

      2。可以执行读操作,我们不能删除元素。
      3.有两种方法可供选择

      • 公共布尔 hasNextElement();
      • 公共对象 nextElement();

      迭代器

      1. 适用于所有收藏

        Iterator itr = c.iterator();  
        where c is any `Collection` class
        
      2. 可以执行读取和删除操作

      3. 三种方法可供选择

        • 公共布尔 hasNext();
        • 公共对象 next();
        • public void remove();

      限制在两者中

      • 仅向前移动
      • Add objectReplace object没有任何方法

      【讨论】:

        【解决方案6】:

        1) Iterator 和 Enumeration 的主要区别在于删除元素 在遍历集合时。迭代器可以在遍历集合期间删除元素,因为它具有 remove() 方法。枚举没有 remove() 方法。

        2) 枚举本质上是故障安全的。如果在遍历期间修改了 Collection,它不会抛出 ConcurrentModificationException。 迭代器本质上是快速失败的。如果在迭代时修改了 Collection 而不是它自己的 remove() 方法,它会抛出 ConcurrentModificationException。

        3) Enumeration 是一个遗留接口,用于遍历 Vector、Hashtable。 迭代器不是遗留接口。 Iterator 可用于 HashMap、LinkedList、ArrayList、HashSet、TreeMap、TreeSet 的遍历。

        【讨论】:

          【解决方案7】:

          如果您正在编写自己的集合类,并且您正在扩展任何现有类或实现任何集合框架接口,那么您基本上别无选择,只能使用 Iterator。

          如果出于某种原因(我想不出),您正在创建一个与 java.util.Collection 或 java.util.Map 无关的自定义集合类,您仍然应该 实现 Iterable 以便人们可以在 for 循环中使用您的类。

          【讨论】:

            【解决方案8】:

            主要的不同是枚举不暴露 remove() 方法。此外,Iterator 不允许同时对底层对象进行导航和修改。他们可以控制是否有并发修改,因此需要更多处理。因此,Enumeration 的性能几乎比 Iterator 快 50%。如果我们只需要导航而忽略此类同步,则只需使用枚举。

            【讨论】:

            • Enumeration 确实“不”公开 remove() 方法 - 但它也没有关注 Collection 的 remove() api 的调用。例如,下面的代码只会打印:AAA、CCC、EEE。 -------------------------------------------------- --- 向量 v=新向量(6); v.add("AAA"); v.add("BBB"); v.add("CCC"); v.add("DDD"); v.add("EEE"); v.add("FFF");枚举 en = v.elements(); while(en.hasMoreElements()) 字符串值=(String) en.nextElement(); System.out.println(值); v.remove(value);
            【解决方案9】:

            Enumeration 只能用于遗留类(Vector, Stack...),而 Iterator 可以用于所有类。

            【讨论】:

              【解决方案10】:

              迭代器和枚举都用于检索数据,不同之处在于枚举只能用于遗留类,即向量/堆栈,而迭代器可用于其余类。枚举也可以用于映射中的键集。

              【讨论】:

              • 您在哪里看到可以对 Map 的键集使用 Enumeration??
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-06-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-10-27
              相关资源
              最近更新 更多