Java枚举和迭代器之间的区别


Answers:


142

查看该Iterator接口的Java API规范,对以下两者之间的区别进行了说明Enumeration

迭代器与枚举有以下两种不同:

  • 迭代器允许调用者在迭代期间使用定义明确的语义从基础集合中删除元素。
  • 方法名称已得到改进。

底线是,既EnumerationIterator会给连续元素,但Iterator以这样的方式得到改善,从而该方法名是短,并且具有附加的remove方法。这是一个并排比较:

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

如Java API规范中所述,对于较新的程序,Iterator应该优先于Enumeration,因为“在Java集合框架中,迭代器代替了枚举”。(根据Iterator规格。)


9
我认为此答案中关于并发性缺少一些解释。
Maarten Bodewes 2012年

@Paul_Draper:编辑不应在帖子中添加新含义,这是评论的目的。
埃米尔(Emil)

2
@coobird您确定“枚举通常更快”吗?因为Enumeration具有“ nextElement()内部的代码块同步”,而且我们在Iterators上没有同步,这会导致ConcurrentModificationException异常?我们称迭代器通常更快,而枚举更安全。??
Kanagavelu Sugumar

@KanagaveluSugumar感谢您指出这一点。(我没有注意到在此答案中添加了额外的讨论。)我已经撤消了编辑,因为它并不完全准确。
coobird 2013年

我认为值得指出的是,remove()是Iterator接口上的可选方法,很多实现类均未实现。
库奇2014年

35

迭代器是快速失败的。例如,当一个线程通过添加/删除操作更改集合时,而另一个线程通过使用hasNext() or next()方法的迭代器遍历该集合时,该迭代器将通过throw 快速失败ConcurrentModificationException。迭代器的快速失败行为只能用于检测错误。由Hashtable,Vector之类的方法返回的Enumeration不是快速失败的,这是通过同步nextElement()锁定当前Vector对象的方法中的代码块来实现的,这需要花费大量时间。


5
仅部分正确:此行为未在接口中定义,这取决于Iterator的实现。确实,java.util中的“旧”集合实现(HashSet,ArrayList等)表现出了这种行为。但是,较新的“并发”集合永远不会引发ConcurrentModificationException,它们将在创建迭代器时遍历该集合。其他实现可能仍然表现出不同的行为。
库奇2014年

1
还值得指出:“请注意,无法保证快速失败行为,因为通常来说,在存在不同步的并发修改的情况下,不可能做出任何硬保证。快速失败操作会尽最大努力抛出ConcurrentModificationException。因此, ,因此编写依赖于此异常的程序的正确性是错误的:ConcurrentModificationException应该仅用于检测错误。” docs.oracle.com/javase/7/docs/api/java/util / ...
Kutzi 2014年

11

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

这是来自枚举接口javadocs的

注意:此接口的功能由Iterator接口复制。此外,Iterator添加了可选的remove操作,并且具有较短的方法名称。新实现应优先考虑使用Iterator而不是Enumeration。


6

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


5

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

枚举
1.仅用于延迟类(例如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();
    • 公共无效remove();

两者的局限性

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

2

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

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


2

主要区别在于枚举不公开remove()方法。而且,Iterator不允许同时导航和修改基础对象。他们可以控制是否有并发的修改,因此需要更多的处理。因此,Enumeration的性能实际上比Iterator快50%。如果只需要导航而忽略这种同步,则使用Enumeration。


的确,枚举不会“不”公开remove()方法-但它也没有注意Collection的remove()api的调用。例如,以下代码将仅打印:AAA,CCC,EEE。-------------------------------------------------- -Vector <String> v =新Vector <String>(6); v.add(“ AAA”); v.add(“ BBB”); v.add(“ CCC”); v.add(“ DDD”); v.add(“ EEE”); v.add(“ FFF”); Enumeration <String> en = v.elements(); while(en.hasMoreElements())字符串值=(String)en.nextElement(); System.out.println(value); v。删除(值);
javauser71 2013年

1

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

2)枚​​举本质上是故障安全的。如果在遍历期间修改Collection,则不会引发ConcurrentModificationException。迭代器本质上是快速失败的。如果在迭代其自身的remove()方法之外的同时修改了Collection,则抛出ConcurrentModificationException。

3)枚举是一个传统接口,用于遍历Vector,Hashtable。迭代器不是旧版接口。迭代器可用于遍历HashMap,LinkedList,ArrayList,HashSet,TreeMap,TreeSet。


0

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


-1

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


您在哪里看到可以对地图的键集使用枚举?
库奇2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.