一、什么是迭代器模式(IteratorPattern)
提供—种方法顺序访问一个聚合对象中各个元素,而又无须暴露该对象的内部实现,属于行为型模式。
应用场景:
—般来说,迭代器模式是与集合是共存的,只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等都有自己的迭代器。JAVA中的iterator迭代器。
二、迭代器的实现方式
模式结构分析:
- 抽象容器(Aggregate)︰提供创建具体迭代器角色的接口,一般是接口,包括一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
- 具体容器角色(ConcreteAggregate):实现抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList, Set接口的哈希列表的实现HashSet等。
- 抽象迭代器角色(lterator)︰负责定义访问和遍历元素的接口,包括几个核心方法,取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移除当前对象的方法remove()
- 具体迭代器角色(Concretelterator)︰实现迭代器接口中定义的方法,并要记录遍历中的当前位置,完成集合的迭代
类关系图:
统一模型:
代码实现:
查看代码
/*
* 抽象迭代器
* */
public interface Iterator {
/**
* 获取下个元素
* @return
*/
Object next();
/**
* 是否有下⼀个
* @return
*/
boolean hasNext();
/**
* 删除元素
* @param obj
* @return
*/
Object remove(Object obj);
}
/*
*具体的迭代器
*
* */
public class ConcreteIterator implements Iterator {
private List list;
private int index = 0;
public ConcreteIterator(List list) {
this.list = list;
}
@Override
public Object next() {
Object obj = null;
if (this.hasNext()) {
obj = this.list.get(index);
index++;
}
return obj;
}
@Override
public boolean hasNext() {
if (index == list.size()) {
return false;
}
return true;
}
@Override
public Object remove(Object obj) {
return list.remove(obj);
}
}
public interface ICollection {
void add(Object obj);
void remove(Object obj);
Iterator iterator();
}
/*
* 容器简化版
* */
public class MyCollection implements ICollection{
private List list = new ArrayList();
@Override
public void add(Object obj) {
list.add(obj);
}
@Override
public void remove(Object obj) {
list.remove(obj);
}
@Override
public Iterator iterator() {
return new ConcreteIterator(list);
}
}
测试用例:
@Test
public void getIterator(){
ICollection collection = new MyCollection();
collection.add("test1");
collection.add("test2");
collection.add("test3");
collection.add("test4");
collection.add("test5");
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
}
测试结果:
test1
test2
test3
test4
test5
方法评估:
优点:
- 可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据
- 支持以不同的方式遍历一个聚合对象
缺点:
- 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐
- 迭代器模式在遍历的同时更改迭代器所在的集合结构会导致出现异常