一、模式解析
迭代子模式又叫游标(Cursor)模式,是对象的行为模式。迭代子模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象
1、迭代子模式一般用于对集合框架的访问,常用的集合框架为list,set,map在实现的时候均可以支持迭代子模式
2、迭代子模式使用同意接口Iterator来完成对象的迭代,一般接口需要实现如下功能:first,next,isDone,currentItem等遍历接口
3、常用的集合框架根据访问需要,可以使用数组,链表等数据结构进行实现,使用迭代子模式可以屏蔽掉数据结构遍历时候产生的差异
4、在java中对结合的增强for循环依赖于迭代子模式实现
二、应用场景
迭代子模式在实际工作中基本无需自己进行编写,因为使用太过频繁,已经被jdk底层进行实现,所以我们使用集合框架时候直接使用就可以了,在这里,我们需要模拟ArrayList的基本实现和迭代子模式的实现。
ArrayList的基本结构为:
1、list内可以存放多个相同类型的元素,
2、元素可以重复存放
3、在jdk底层采用数组进行模拟,当存放数据容量超出数组,会对数组进行扩容,自动增加一部分容量,扩容算法为:(this.elementData.length*3)/2+1
4、继承了Iterator,可以使用迭代器进行遍历
三、场景代码
1、Iterator接口,定义迭代方法
package iterator.example; /** * 定义迭代器的接口 * @author zjl * @time 2016-2-3 * */ public interface Iterator<E> { public E first(); public E next(); public boolean isDone(); public int currentItem(); }
2、定义list接口,为了简化处理,此处直接继承迭代器接口
package iterator.example; public interface List<E> extends Iterator<E> { public int size(); public boolean isEmpty(); public E remove(int index); public int indexOf(E e); void add(E e); public E get(int index); }
3、定义Arraylist,实现各方法
package iterator.example; import java.util.Arrays; public class ArrayList<E> implements List<E>{ //初始化一个数组,来保存对象 Object[] elementData; private int size=0; //迭代器游标 private int cursor=0; //数组初始化 public ArrayList(int init){ elementData=new Object[init]; } //默认构造类型,默认初始化10个元素 public ArrayList(){ this(10); } @Override public int size() { return this.size; } @Override public boolean isEmpty() { return this.size==0; } @Override public void add(E e) { //如果list长度等于数组长度,那么将数组扩大 ensureCapacity(this.size+1); elementData[this.size++]=e; } @Override public E remove(int index) { RangeCheck(index); //移除指定位置的元素 E e= (E) elementData[index]; for(;index<this.size;index++){ elementData[index]=elementData[index+1]; } elementData[index--]=null; return e; } @Override public int indexOf(E e) { // TODO Auto-generated method stub return 0; } //判断是否超长,如果超长,则扩展数组 public void ensureCapacity(int minCapacity){ int oldCapacity=this.elementData.length; if(minCapacity>oldCapacity){ int newLength=(this.elementData.length*3)/2+1; Object[] oldDate=this.elementData; this.elementData=Arrays.copyOf(elementData, newLength); } } private void RangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); } @Override public E first() { return (E) elementData[0]; } @Override public E next() { if(isDone()){ throw new IndexOutOfBoundsException("the list is done"); } return (E) elementData[cursor++]; } @Override public boolean isDone() { return cursor==size; } @Override public int currentItem() { // TODO Auto-generated method stub return cursor; } @Override public E get(int index) { RangeCheck(index); return (E) elementData[index]; } }