这两个接口有什么确切的区别呢?使用 Enumeration
是否比使用Iterator
更有优势?如有详细解释和参考文章将不胜感激。
这两个接口有什么确切的区别呢?使用 Enumeration
是否比使用Iterator
更有优势?如有详细解释和参考文章将不胜感激。
查看Java API规范中Iterator
接口的说明,其中解释了与Enumeration
之间的区别:
迭代器和枚举有两个不同之处:
- 迭代器允许调用者在迭代期间以明确定义的语义从底层集合中删除元素。
- 方法名称已得到改进。
总的来说,Enumeration
和Iterator
都会提供连续的元素,但是Iterator
通过缩短冗长的方法名来改进方法,并增加了一个remove
方法。以下是并排比较的示例:
Enumeration Iterator
---------------- ----------------
hasMoreElements() hasNext()
nextElement() next()
N/A remove()
正如Java API规范中所提到的,对于新程序,应优先使用Iterator
而非Enumeration
,因为“在Java集合框架中,Iterator取代了Enumeration的位置。”(来自Iterator
规范)
迭代器是快速失败的(fail-fast)。即当一个线程通过添加/删除操作更改集合,而另一个线程正在使用hasNext()或next()
方法遍历它时,迭代器会快速地抛出ConcurrentModificationException
。迭代器的快速失败行为仅用于检测错误。由类似于Hashtable、Vector的类的方法返回的枚举不是快速失败的,这是通过在nextElement()
方法内同步代码块来实现的,该代码块锁定当前Vector对象,这需要花费大量时间。
“官方”上讲,迭代器接口支持额外操作(例如删除)并且与枚举接口相似。通常倾向于使用迭代器。
下面是来自枚举接口javadoc的内容:
注意:此接口的功能与迭代器接口重复。此外,迭代器还添加了一个可选的remove操作,并且方法名称更短。新实现应优先考虑使用迭代器而不是枚举。
枚举(Enumeration
)和迭代器(Iterator
)有三个区别:
枚举(Enumeration)
它只用于遗留类(例如Vector
)
// v是Vector类的一个对象
Enumeration e = v.elements();
我们不能删除元素,集合本身不能被改变;只能访问元素
以下两个方法是可用的:
public boolean hasNextElement()
public Object nextElement()
迭代器
它适用于集合框架中的所有集合:
// c 是任何集合
classIterator itr = c.iterator();
可以同时迭代和访问元素,并且可以删除元素。
有三种方法可用
public boolean hasNext()
public Object next()
public void remove()
枚举和迭代器
的限制:
之前的回答中没有提到的一个简单事实是,Iterator<T>
与 Iterable<T>
结合使用,用于解释 for(_type_ element:collection){...}
结构。
1) 迭代器(Iterator)和枚举(Enumeration)之间的主要区别在于在遍历集合时是否可以删除元素。由于迭代器具有remove()方法,因此在遍历集合期间可以删除元素。而枚举没有remove()方法。
2) 枚举是安全失败的。如果在遍历期间修改了集合,它不会抛出ConcurrentModificationException异常。 迭代器是快速失败的。如果在迭代除自己的remove()方法以外的集合时进行修改,它将抛出ConcurrentModificationException异常。
3) 枚举是一个遗留的接口,用于遍历Vector、Hashtable等类。 迭代器不是遗留接口,可用于HashMap、LinkedList、ArrayList、HashSet、TreeMap、TreeSet等类的遍历。
主要区别在于Enumeration不公开remove()方法。此外,Iterator不允许同时导航和修改基础对象。它们有一个控制器来查看是否存在并发修改等情况,因此需要更多的处理。因此,Enumeration的性能几乎比Iterator快50%。如果我们只需要导航而忽略这种同步,只需使用Enumeration。
如果您正在编写自己的集合类,并且您正在扩展任何现有类或实现任何Collections框架接口,则基本上没有选择,只能使用Iterator。
如果您出于某种原因(我想不到)创建了一个与java.util.Collection或java.util.Map没有任何关系的自定义集合类,您仍应该实现Iterable,以便人们可以在for循环中使用您的类。
枚举只能用于旧类(Vector, Stack...),而迭代器可以用于所有类。
迭代器和枚举都用于检索数据,区别在于枚举只能用于旧类,例如vector/stack,而迭代器可以用于其他类。枚举也可用于地图中的键集。