什么是迭代器模式

所谓迭代器模式,就是提供一种方法顺序访问一个容器对象的各个元素,而又不需要暴露该对象的内部表示的设计模式。

迭代器模式的实现方式

在客户访问类与容器体之间插入一个第三者——迭代器,就可以在不暴露该对象的内部表示的同时解决容器类承担提供遍历方法功能造成功能冗余的问题。

《水浒传》中“梁山泊全伙受招安”的时候,宋江给梁上好汉造了天罡地煞两个花名册(容器)。先定义一个容器接口:

public interface Company {

Iterator iterator();

}

天罡容器:

public class SkyCompany implements Company {

private List<Bawcock> list = new ArrayList<>();

public SkyCompany() {
list.add(new Bawcock("宋江","呼保义","天魁星","兵马大元帅"));
//此处省略34行代码
list.add(new Bawcock("燕青","浪子","天巧星","步军统领兼谍报队长"));
}

public List<Bawcock> getList(){
return list;
}

@Override
public Iterator iterator() {
return new SkyIterator(list);
}
}

地煞容器:

public class LandCompany implements Company {

private List<Bawcock> list = new ArrayList<>();

public LandCompany() {
list.add(new Bawcock("朱武","神机军师","地魁星","军师参赞"));
//此处省略70行代码
list.add(new Bawcock("段景住","金毛犬","地狗星","机密情报营头领"));
}

public List<Bawcock> getList(){
return list;
}

@Override
public Iterator iterator() {
return new LandIterator(list);
}
}

天罡迭代器:

public class SkyIterator implements Iterator {

private List<Bawcock> bawcockList;
private int position;

public SkyIterator(List<Bawcock> bawcockList) {
this.bawcockList = bawcockList;
}

@Override
public boolean hasNext() {
return !(position > bawcockList.size() - 1 || bawcockList.get(position) == null);
}

@Override
public Object next() {
Bawcock bawcock = bawcockList.get(position);
position++;
return bawcock;
}
}

地煞迭代器:

public class LandIterator implements Iterator {

private List<Bawcock> bawcockList;
private int position;

public LandIterator(List<Bawcock> bawcockList) {
this.bawcockList = bawcockList;
}

@Override
public boolean hasNext() {
return !(position > bawcockList.size() - 1 || bawcockList.get(position) == null);
}

@Override
public Object next() {
Bawcock bawcock = bawcockList.get(position);
position++;
return bawcock;
}
}

好汉类:

public class Bawcock {

private String name;//姓名
private String nickname;//绰号
private String constellation;//星座
private String position;//职位

public Bawcock(String name, String nickname, String constellation, String position) {
this.name = name;
this.nickname = nickname;
this.constellation = constellation;
this.position = position;
}

@Override
public String toString() {
return "Bawcock{" +
"name='" + name + '\'' +
", nickname='" + nickname + '\'' +
", constellation='" + constellation + '\'' +
", position='" + position + '\'' +
'}';
}
}

皇帝可以用迭代器检阅梁山好汉的花名册:

public static void check(Iterator iterator){
while(iterator.hasNext()){
Log.e("皇帝翻阅花名册",iterator.next().toString());
}
}

但是如果皇帝想要修改梁山好汉的职位的时候:“令宋江等分开军马,各归原所”,就会得到这个的答复:“俺等众头领,生死相随,誓不相舍!端的要如此,我们只得再回梁山泊去”。尽管道君皇帝宋徽宗碰了一鼻子灰,但我们明白了迭代器模式如何保证数据的安全。

Android源码中的迭代器模式

(1)List和Map

迭代器模式一般不会交给开发者实现,Java的常见数据结构List和Map等都自带迭代器。

(2)SQLiteDatabase

当我们使用SQLiteDatabase的query方法查询数据库时,会返回一个Cursor游标对象,这就是一个迭代器。

Android开发中如何利用迭代器模式

迭代器模式的优点很明显:支持以不同的方法去遍历一个容器对象,也可以有多个遍历,弱化了容器类与遍历算法之间的关系。在遍历一个容器对象时迭代器模式作用非常明显,比如自定义一个支持多选的图片选择器。

需要注意的几个问题

(1)迭代器模式在Java语言中具有相应的内置实现,极少数情况才需要开发者自己实现迭代器。

(2)迭代器模式增加类文件,造成代码臃肿。