文章目录
一、迭代器的功能
1. Iterator接口
Iterator,它总是用同一种逻辑来遍历集合。使得客户端自身不需要来维护集合的内部结构,所有的内部状态都由Iterator来维护。客户端不用直接和集合进行打交道,而是控制Iterator向它发送向前向后的指令,就可以遍历集合。
在Java中Iterator
为一个接口,它只提供了迭代的基本规则。在JDK中它是这样定义的:对Collection进行迭代的迭代器。迭代器取代了Java Collection Framework中的Enumeration
。迭代器与枚举有两点不同:
1. 迭代器在迭代期间可以从集合中移除
元素。
2. 方法名得到了改进,Enumeration的方法名称都比较长。
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
2.Iterable接口
Java中还提供了一个Iterable接口
,Iterable接口实现后的功能是**‘返回**’一个迭代器,我们常用的Collection接口都实现了该接口。
该接口的iterator()方法
返回一个标准的Iterator实现。实现Iterable接口允许对象成为Foreach语句的目标。就可以通过foreach语句来遍历你的底层序列。
二、迭代器的使用
在 Java SE 8 中, 甚至不用写循环 。 可以调用 forEachRemaining 方法并提供一lambda表达式 ( 它会处理一个元素 )。 将对迭代器的每一个元素调用这个 lambda 表达式 , 直到再没有元素为止。
iterator.forEachRemaining(element -> do something with element);
//得到迭代器来遍历数组。迭代器与数组是相辅相成的
Iterator it =c.iterator();//通过集合的方法返回迭代器对象
while (it.hasNext()){
String s= (String) it.next();
System.out.println(s);
}
注释 : 编程老手会注意到 : Iterator 接口的 next 和 hasNext 方法与 Enumeration 接口的nextElement 和 hasMoreElements 方法的作用一样。 Java 集合类库的设计者可以选择使用Enumeration 接口。 但是 , 他们不喜欢这个接口累赘的方法名 ,于是引入了具有较短方法名的新接口。
Java 迭代器认为是位于两个元素之间 。 当调用 next 时 , 迭代器就越过下一个元素 , 并返回刚刚越过的那个元素的引用 ( 见图 9 - 3 )
更重要的是, 对next 方法和 remove 方法的调用具有互相依赖性。 如果调用remove 之前没有调用 next 将是不合法的 。 如果这样做 , 将会抛出一个IllegalStateException
异常。
如果想删除两个相邻的元素 , 不能直接地这样调用 :
it.remove ();
it.remove (); // Error !
相反地, 必须先调用 next 越过将要删除的元素 。
it,remove () ;
it.next () ;
it.remove () ; // OK
3. Iterator 迭代器会存在并发修改异常
详情请看ArrayList源码,ArrrayList有一个名为 Itr的内部类,该类就是一个继承了普通Iterator接口的迭代器。
4. Iterator 与 listIterator的区别
大致的回答
- listIterator 接口继承自 Iterator接口
- Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
- Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
- 阅读ArrayList源码时你会发现,listeriterator在遍历时避免了并发修改异常。
ListIterato拓展的新功能,比如:
- previous :与next一样,它会返回刚刚光标越过的对象(假定光标就代表着迭代器的位置)
- remove :删除刚刚越过的对象
- add:遍历时可在当前光标的前面增加一个元素
- set :替换一个元素,
- nextIndex:获取当前光标的下一个元素
- previousIndex :获取当前光标的前一个元素
注意listIterator的遍历方向问题,在《Java核心技术卷1》第九章的集合链表里有这样一段:
该段表示 remove时,总是根据迭代器位置以及方向,确定删除的元素是迭代器刚刚越过的元素。