什么是迭代器
迭代器是一个对象,它的工作是遍历并且选择序列中的对象(比如一个ArrayList),而客户端程序员不必知道或关心该序列底层的结构。此外,迭代器通常被称为轻量级对象:创建它的代价很小,经常可以看到对迭代器有一些奇怪的限制,例如,Java中的iterator只能单向移动,这个Iterator只能用来:
- 使用iterator()方法要求容器返回一个Iterator对象。Iterator将准备好返回序列的第一个元素。
- 使用next()或者序列中的写一个元素。
-使用hasNext()方法检查序列中是否还有元素。
- 使用remove()方法将讲迭代器新返回的元素删除。
实例分析
package com.hand.hsp;
import java.util.*;
/**
* Created by Moxie on 2016/12/25.
*/
public class TestIterator {
public static void main(String[] args){
List<Integer> list = new ArrayList<Integer>();
for(int i = 0 ; i < 10 ; i++){
list.add(i);
}
//调用ArrayList的iterator()方法返回一个 Iterator 对象
Iterator<Integer> iterator = list.iterator();
//从第一个元素开始遍历,每次获取一个新的元素
while(iterator.hasNext()){
int number = iterator.next();
System.out.print(number + " ");
}
System.out.println();
int k = 0;
iterator = list.iterator();
while(k++ < 5 && iterator.hasNext()){
/**
* 注意下面这两条语句的顺序,第一次执行iterator.next()的时候取到的是第一个元素,然后再remove。
* 如果顺序相反,则会抛出异常Exception in thread "main" java.lang.IllegalStateException,
* 意思就是:在不合理或不正确时间内唤醒一方法时出现的异常信息。换句话说,
* 即 Java 环境或 Java 应用不满足请求操作。
*/
iterator.next();
iterator.remove();
}
while(iterator.hasNext()){
int number = iterator.next();
System.out.print(number + " ");
}
}
}
原理分析
Iterator的用途我们已经看到了,那么,它究竟是怎么实现的呢?这时候我们找到Iterator接口,发现它只声名了下面这几个方法
然后我们再找到ArrayList的iterator()方法,看看它是怎么实现的,从 833行开始,到903行(JDK1.8)
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
看了源代码,是不是觉得有点熟悉?它是通过一个名叫 Itr 的内部类实现的,逻辑代码都写在内部类里面。这不是那种什么设计模式吗?好吧,我说不出来,只是觉得哪里看过。我们平时调用的iterator()方法,就是这样实现的,看了源码是不是觉得清爽了好多?