迭代器模式又稱游標模式躏将,也是行為型設計模式。源于對容器的訪問考蕾,主要解決容器的遍歷操作耸携。
我們隊容器的訪問必然會用到遍歷。我們可以將遍歷的方法封裝到容器中辕翰,或者不提供遍歷方法夺衍。如果封裝在容器中,容器就承擔了過多的功能喜命。如果不提供遍歷方法沟沙,使用者會自己去實現(xiàn)遍歷方法,讓容器內(nèi)部細節(jié)暴露無遺壁榕。
因此在訪問類和容器之間加上了第三者--迭代器矛紫。
定義
提供一種方法訪問一個容器對象中各個元素,而又不暴露該對象的內(nèi)部細節(jié)牌里。
使用場景
- 遍歷一個容器對象時颊咬。
UML
- Iterator : 迭代器接口,負責定義牡辽、訪問喳篇、遍歷元素的接口。
- ConcreteIterator:具體的迭代類态辛,實現(xiàn)迭代器接口麸澜,并記錄遍歷的當前位置。
- Aggregate:容器接口奏黑,負責提供創(chuàng)建具體迭代器的接口炊邦。
- ConcreteAggregate:具體容器類,和具體迭代器相關(guān)聯(lián)熟史。
模板代碼
抽象的迭代器
public interface Iterator<T>{
boolean hasNext();
T next();
}
具體的迭代器
public class ConcreteIterator<T> implements Iterator<T> {
private List<T> list = new ArrayList<>();
private int cursor = 0;
public ConcreteIterator(List<T> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return cursor!=list.size();
}
@Override
public T next() {
T obj = null;
if (this.hasNext()){
obj = list.get(cursor++);
}
return obj;
}
}
抽象的容器
public interface Aggregate<T> {
void add(T obj);
void remove(T obj);
Iterator<T> iterator();
}
具體的容器
public class ConcreteAggregate<T> implements Aggregate<T> {
private List<T> list = new ArrayList<>();
@Override
public void add(T obj) {
list.add(obj);
}
@Override
public void remove(T obj) {
list.remove(obj);
}
@Override
public Iterator<T> iterator() {
return new ConcreteIterator<>(list);
}
}
客戶端調(diào)用
public class Client {
public static void main(String[] args) {
Aggregate aggregate = new ConcreteAggregate();
aggregate.add("a");
aggregate.add("r");
aggregate.add("f");
aggregate.add("w");
aggregate.add("e");
Iterator iterator = aggregate.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
輸出
簡單實現(xiàn)
可以直接用上面的模板代碼馁害,集合是泛型,存什么都可以蹂匹。因為迭代器就是用來遍歷的碘菜。
Android中的迭代器模式
其實在上面的例子中用List來存儲本來就是不合適的。因為Java本身提供的容器都已經(jīng)提供了相應的迭代器。所以在開發(fā)中炉媒,我們基本不需要親自去實現(xiàn)踪区。
Android中的迭代器例子有一個是SQLite數(shù)據(jù)庫的查詢了。
SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null,SQLiteDatabase.OPEN_READWRITE);
Cursor cursor = db.rawQuery("select * from android_basic , 15",null);
返回的是一個Cursor對象吊骤,這個對象實質(zhì)是其實就是個迭代器缎岗。看看他的用法白粉。
while (cursor.moveToNext()){//遍歷讀取數(shù)據(jù)
......
}
總結(jié)
迭代器就是把容器中遍歷對象的功能提取出來传泊,這樣既不暴露容器的細節(jié),又可以讓外部訪問容器內(nèi)部的內(nèi)容鸭巴。
優(yōu)點
- 支持不同的方式去遍歷一個容器眷细,也可以有多個遍歷,弱化了容器和遍歷算法之間的關(guān)系鹃祖。
- 不用用戶自己去實現(xiàn)遍歷功能溪椎,也分離了容器和遍歷算法,避免了容器承擔過多功能恬口。
- 封裝性更好校读,方便修改遍歷算法而不用修改容器。
缺點
- 類文件會增加祖能,所以對于簡單的遍歷來說不是很重要歉秫。