Java中的集合(十五) Iterator 和 ListIterator、Enumeration
Java中的集合(十五) Iterator 和 ListIterator、Enumeration
一、Iterator
(一)、简介
Iterator 是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。把访问逻辑从不同类型的集合类中抽取出来,从而避免向外部暴露集合的内部结构。
(二)、常用API
实例:
(三)、特点
-
- 只能单向移动遍历。
- 迭代器在迭代期间可以从集合中移除元素(通过迭代器删除)。
- 不能在迭代时通过集合对象添加,删除元素。
(四)、相关问题
1、Iterator遍历时不可以删除、添加集合中的元素问题
集合对象创建迭代器时,迭代器维护了 expectedModCount 属性,该属性记录了集合的大小(modCount),当集合对象调用 add()、remove() 等有可能修改集合长度的方法时,modCount 修改了,而 expectedModCount 没有及时更新,就会抛出 ConcurrentModificationException 异常。
2、移除元素
iterator.remove()是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为。而且每调用一次next()方法,remove()方法只能被调用一次,如果违反这个规则将抛出 IllegalStateException 异常。
二、ListIterator
(一)、简介
ListIterator是一个功能更加强大的迭代器,它继承于 Iterator 接口,只能用于各种 List 集合类型及其子类的访问。可以通过调用 listIterator() 方法产生一个指向 List 集合的ListIterator,,还可以调用 listIterator(n) 方法创建一个一开始就指向列表索引为n的元素处的 ListIterator。
(二)、常用API
(三)、特点
-
- 支持双向遍历(正向 / 反向遍历)。
- 产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引。
- 提供丰富的API对集合的操作。
- 可以使用add()方法在next()方法返回的元素之前或previous()方法返回的元素之后插入一个元素。
- 可以使用set()方法替换它访问过的最后一个元素。
(四)、允许遍历时添加、删除和修改的问题
ListIterator在执行添加、删除等更新操作时,会同时更新 expectedModCount 和 modCount 属性。
三、迭代器遍历、删除图示
(一)、遍历
(二)、删除
四、Enumeration
(一)、简介
Enumeration(枚举器)接口的作用和 Iterator 类似,但是只提供了遍历Vector和Hashtable类型集合元素的功能,不支持元素的移除操作。
(二)、常用API
(三)、特点
-
- 只可以遍历 Vector 和 Hashtable类型的集合。
- 不支持fail-fast机制。
- 遍历速度比迭代器快。
五、Iterator和ListIterator的区别
- ListIterator有add()方法,可以向List中添加对象,而Iterator不能
- ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。
- ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。
- 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。
六、Iterator和Enumeration的区别
- 任何集合对象都可以使用Iterator遍历,Enumeration只能遍历 Vector 和 Hashtable 类型的集合对象。
- Enumeration只提供遍历的功能,Iterator不仅提供遍历,还可以执行删除操作。
- Iterator支持fail-fast机制,而Enumeration不支持。