什么是迭代器模式
迭代器模式的角色构成
迭代器角色(Iterator)
定义遍历元素所需要的方法,一般来说会有三种方法:next()方法取到当前的元素并且移动到下一个元素的位置;hasNext()方法:判断是否遍历结束的方法;remove()方法:移出当前对象的方法。
具体迭代器角色(Concrete Iterator)
实现迭代器接口中定义的方法,完成集合的迭代;eg:ArrayList中的Itr。
容器角色(Aggregate)
一般是一个接口,提供一个iterator()方法;eg:例如Java中的Colletion接口,List接口,Set接口等。
具体容器角色(Concrete Aggregate)
就是抽象容器的具体实现类;比如List接口的有序列表ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet。
Iterator接口
Iterator接口也是集合框架库的成员,它与Collection系列、Map系列的集合不一样,Collection、Map系列集合主要存放其他对象,而Iterator则主要用于遍历Collection集合中的元素,Iterator对象也被称之为迭代器。Iterator接口隐藏了Collection实现类的底层细节,向应用程序提供了遍历Collection集合元素的统一编程接口。
Iterator接口中定义了如下四种方法:
1)Boolean hasNext()
如果被迭代的集合元素还没有被遍历完,则返回true;
2)Object next()
返回集合里的下一个元素;
3)void remove()
删除集合里上一次next()返回的元素;
4)void forEachRemainning(Consumer action)
通过lambda表达式来遍历集合元素。
迭代器的实现
Iterable接口中有一个iterator()方法返回一个Iterator对象,所以我们要实现一个迭代器,首先要重写Iterable接口当中的iterator()方法,由于iterator()返回一个Iterator对象,所以在iterator()中要实现返回一个Iterator内部类对象。该类中也要重写Iterator接口中的hasNext(),next()方法。
下面是以ArrayList为例实现迭代器模式:
mport java.util.Arrays;
import java.util.Iterator;
public class MyArrayList<T> implements Iterable<T> {
private T[] element;
private int size;
public MyArrayList(){
this.size = 0;
}
public MyArrayList(int n){
this.element = (T[]) new Object[n];
this.size = 0;
}
private boolean isFull(){
return size == element.length;
}
private void expend(){
element = Arrays.copyOf(element,element.length+element.length>>1);
}
public T get(int index){
return element[index];
}
public void add(T elem){
if (isFull()){
expend();
}
element[size++] = elem;
}
public boolean isEmpty(){
return size == 0;
}
public void remove(int index){
if (index >=size || index < 0){
return;
}
int numMoved = size-index-1;
System.arraycopy(element,index+1,element,index,numMoved);
element[size] = null;
size--;
}
public void set(int index,T value){
element[index] = value;
}
@Override
public Iterator<T> iterator() {
return new MyIterator();
}
class MyIterator implements Iterator<T>{
private int index = 0;
@Override
public boolean hasNext() {
return index < size;
}
@Override
public T next() {
T val = MyArrayList.this.element[index];
index++;
return val;
}
@Override
public void remove() {
MyArrayList.this.remove(index);
}
}
}