迭代器模式
- 概念
- 使用场景
- 类图
- 代码实例
概念
屏蔽了具体集合、数组、列表的遍历方式和具体遍历的对象, 是一种获取集合中元素的一种方式。 提供一个抽象迭代接口,里面有 hashNext() 是否有下一个元素, next()下一个元素,first()获取第一个元素等方法。 这个迭代接口由具体集合来实现,并返回一个迭代器,上层不需要关心迭代的对象是什么以及内部是以何种方式(逆序还是顺序方式)。
使用场景
1、当你需要使用多种遍历方式进行对集合迭代时
2、当你只需要遍历出一个一个元素,具体是迭代集合还是数组元素我们并不需要关心
类图
Container:容器类,封装了数据的基本操作,里面使用数组实现的,并且实现了两种遍历元素方式
Iterator:抽象迭代器接口,由在Container内通过匿名类实现其迭代器接口的方法
Client:客户端测试
代码实例
Container 容器类,并且实现了两种遍历该容器的方式,但是对于遍历该容器者来说不需要关心具体的实现细节以及遍历的对象是数组还是集合,只需要获取Iterator迭代器就能遍历出所有元素
/**
* @author duanyimiao
* @create 2018-10-19 10:03 AM
* @description 容器类 下面只是简单实现了下,具体数据校验和异常都没有考虑,这里仅仅为了体会下迭代器模式
**/
public class Container {
private Object[] elements;
private int size = 0;
public Container() {
}
public Container(int initialCapacity) {
elements = new Object[initialCapacity];
}
public void add(Object obj) {
//需要判断 size是超过了initialCapacity,若超过则需要扩容数组
elements[size++] = obj;
}
public Object remove(int index) {
Object obj = elements[index];
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elements, index + 1, elements, index, numMoved);
}
//let gc do it work
elements[--size] = null;
return obj;
}
/**
* 从头到尾遍历
*
* @return
*/
public Iterator iteratorByOrder() {
return new Iterator() {
//下一个元素的序号 默认从0开始
int cursor;
@Override
public boolean hashNext() {
return cursor != size;
}
@Override
public Object next() {
int i = cursor;
if (i >= size) {
throw new IndexOutOfBoundsException();
}
Object[] elements = Container.this.elements;
cursor = i + 1;
return elements[i];
}
};
}
/**
* 从尾到头遍历
*
* @return
*/
public Iterator iteratorByReverse() {
return new Iterator() {
//下一个元素的序号 默认从size-1开始
int cursor = size-1;
@Override
public boolean hashNext() {
return cursor >= 0;
}
@Override
public Object next() {
int i = cursor;
if (i < 0) {
throw new IndexOutOfBoundsException();
}
Object[] elements = Container.this.elements;
cursor = i-1;
return elements[i];
}
};
}
}
Iterator 抽象迭代接口
/**
* @author duanyimiao
* @create 2018-10-19 10:17 AM
* @description 抽象迭代接口
**/
public interface Iterator {
boolean hashNext();
Object next();
}
Client 测试类
/**
* @author duanyimiao
* @create 2018-10-19 10:36 AM
* @description
**/
public class Client {
public static void main(String[] args) {
Container container = new Container(8);
container.add("1");
container.add("2");
container.add(3);
//采用从头到尾遍历方式
Iterator iteratorByOrder = container.iteratorByOrder();
//注意 我们常用的 for(元素 param1 : 集合对象) 内部也是通过iterator来实现的
while(iteratorByOrder.hashNext()){
System.out.print(iteratorByOrder.next());
}
//采用从尾到头遍历方式
container.remove(2);
Iterator iteratorByReverse = container.iteratorByReverse();
while(iteratorByReverse.hashNext()){
System.out.print(iteratorByReverse.next());
}
}
}
输出结果
12321