1 Iterator接口
在程序开发中,经常需要遍历集合中的所有元素。
针对这种需求,JDK专门提供了一个接口java.util.Iterator
,主要用于迭代访问(即遍历)Collection
中的元素,因此Iterator
对象也被称为迭代器。迭代器是所有单列集合通用的遍历方式。
想要遍历Collection集合,那么就要获取该集合迭代器完成迭代操作,下面介绍一下获取迭代器的方法:
public Iterator iterator()
: 获取集合对应的迭代器,用来遍历集合中的元素的。
下面介绍一下迭代的概念:
- 迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续判断,如果还有就再取出来。直到集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
Iterator接口的常用方法如下:
public boolean hasNext()
:判断集合中是否存在下一个元素public E next()
:返回迭代的下一个元素。
代码示例:
public class IteratorDemo {
public static void main(String[] args) {
// 使用多态方式 创建对象
Collection<String> coll = new ArrayList<String>();
// 添加元素到集合
coll.add("张三");
coll.add("李四");
coll.add("王五");
//遍历
//使用迭代器遍历,每个集合对象都有自己的迭代器
Iterator<String> it = coll.iterator();
//泛型指的是迭代出的元素的数据类型
while(it.hasNext()){ //判断是否有迭代元素
String s = it.next();//获取迭代出的元素
System.out.println(s);
}
}
}
注意:
- 在进行集合元素取出时,如果集合中已经没有元素了,还继续使用迭代器的next方法,将会发生
java.util.NoSuchElementException
没有集合元素异常。 - 在进行集合元素获取时,如果添加或移除集合中的元素 , 将无法继续迭代 , 将会抛出
java.util.ConcurrentModificationException
并发修改异常
2 迭代器遍历集合元素的过程
当遍历集合时,首先通过调用集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。
迭代器遍历集合元素的过程:
在调用Iterator的next方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一次调用迭代器的next方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next方法时,迭代器的索引会指向第二个元素并将该元素返回,依此类推,直到hasNext方法返回false,表示到达了集合的末尾,终止对元素的遍历。
3 迭代器源码分析
迭代器是遍历Collection集合的通用方式,任意Collection集合都可以使用迭代器进行遍历,那么每一种集合的自身特性是不同的,也就是存储元素的方式不同,那么是如何做到遍历方式的统一呢,接下来我们以ArrayList集合为例分析一下迭代器的源代码。
java.util.Iterator
接口,定义遍历集合元素相关的 hasNext()、next() 方法
public interface Iterator<E> {
boolean hasNext();
E next();
}
java.util.Collection
接口,定义了方法 iterator(),返回对集合中元素进行迭代(遍历)的 Iterator 接口实现类的迭代器对象。
public interface Collection<E> {
Iterator<E> iterator();
}
java.util.ArrayList
类, ArrayList 类中定义内部类 Itr 实现接口 Iterator 重写hasNext()、next()方法; ArrayList 类实现List接口,即实现了Collection接口,重写 iterator() 方法创建并返回内部类 Itr 的对象,因此ArrayList集合对象调用 iterator()方法即返回迭代器对象。
public class ArrayList<E> implements List<E> {
/**
* ArrayList实现接口Collection
* 重写方法iterator()
* 返回Iterator接口实现类 Itr类的对象
*/
public Iterator<E> iterator() {
return new Itr();
}
/**
* ArrayList中定义内部类Itr,实现接口Iterator
* 重写hasNext()、next()方法
*/
private class Itr implements Iterator<E> {
public boolean hasNext() {...}
public E next() {...}
}
}
结论
- 所有Collection集合的迭代器,全由内部类实现。
- 集合中定义内部类,实现迭代器接口,可以使所有Collection集合的遍历方式统一。
- 调用迭代器的方法hasNext(),next()均执行集合中内部类的重写方法。