迭代器模式(Iterator)
1、概述
迭代器模式针对的对象是集合类(Tips:这里的集合类泛指存入多个元素的类),使得该集合类拥有访问该集合类所有元素的迭代器类,并通过迭代器类获取该集合类的每一个元素,而且不暴露内部元素细节。
2、应用场景
①应用的对象必须是可遍历的集合类
②需要对集合类的内部元素进行批量取出
③不能暴露内部元素的细节
我们所熟知的Java Collection架构就利用到了迭代器模式,所有的Collection中都有一个方法:iterator(),用于获得该集合类的迭代器,迭代器中存储了该集合类的每个元素,并提供previous、next方法取出相应的元素,hasNext用于判断是否已到元素列表的最后。
3、实例
我们可以模仿Java SE原生的Collection集合框架来自己实现一个迷你版集合类,这款迷你版的集合类就利用迭代器模式,代码如下。
import java.util.Arrays;
/**
* @author Hanlin Wang
*/
public class IteratorMode {
public static void main(String[] args) {
MyCollection<String> mycol = new MyCollection<String>();
mycol.add("qwe");
mycol.add("asd");
mycol.add("zxc");
Iterable<String> it = mycol.iterator();
while (it.hasNext()) {
String next = it.next();
System.out.println(next);
}
}
}
// 定义集合接口
interface Collection<E> {
//迭代器
Iterable<?> iterator();
// 增加元素
void add(E e);
// 删除元素
void remove(int index);
// 改变元素
void set(int index, E e);
// 获取指定索引的元素
E get(int index);
// 获取集合大小
int getSize();
}
// 定义实现Collection接口的类MyCollection
class MyCollection<E> implements Collection<E> {
// 定义数据类型为Object
private transient Object[] data;
private static final Object[] EMPTY_DATA = {};
private static final Exception ArrayIndexOutOfBoundsException = null;
private int cursor = -1;
// 构造方法,初始化集合数据的容量。
public MyCollection() {
this.data = EMPTY_DATA;
}
@Override
public void add(E e) {
// TODO Auto-generated method stub
++cursor;
data = Arrays.copyOf(data, data.length + 1);
data[cursor] = e;
}
@Override
public void remove(int index) {
// TODO Auto-generated method stub
if (index >= 0 && index <= data.length - 1) {
data[index] = data[data.length - 1];
data = Arrays.copyOf(data, data.length - 1);
--cursor;
} else {
try {
throw ArrayIndexOutOfBoundsException;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void set(int index, E e) {
// TODO Auto-generated method stub
try {
if (index >= 0 && index <= data.length - 1) {
data[index] = e;
}
} catch (ArrayIndexOutOfBoundsException e2) {
e2.printStackTrace();
}
}
@Override
public E get(int index) {
// TODO Auto-generated method stub
try {
if (index >= 0 && index <= data.length - 1) {
return (E) data[index];
}
} catch (ArrayIndexOutOfBoundsException e2) {
e2.printStackTrace();
}
return null;
}
@Override
public int getSize() {
// TODO Auto-generated method stub
return data.length;
}
@Override
public Iterable iterator() {
// TODO Auto-generated method stub
return new MyIterator(this);
}
}
//定义迭代器接口
interface Iterable<E>{
E previous();
E next();
boolean hasNext();
}
//定义迭代器
class MyIterator<E> implements Iterable<E>{
private Collection<?> col;
private int pos = -1;
public MyIterator(Collection<?> col){
this.col = col;
}
@Override
public E previous() {
// TODO Auto-generated method stub
if(pos > 0){
pos--;
return (E) col.get(pos);
}
return null;
}
@Override
public E next() {
// TODO Auto-generated method stub
if(pos < col.getSize()-1){
pos++;
return (E) col.get(pos);
}
return null;
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
if (pos < col.getSize()-1) {
return true;
} else {
return false;
}
}
}
这是本人阅读Collection集合框架源代码后,自己做的一个迷你版集合。建议大家先去研究一下Java SE的Collection框架,尝试着自己写一个属于自己的集合类。