定義
提供一種方式順序訪問一個容器對象中的各個元素,而又不需要暴露該對象的內部結構;
在Java中使用最多的一種模式就是迭代器模式,但是對于程序員來說,自己寫代碼使用迭代模式并不多,因為大部分集合已經自帶了迭代器,但是我們需要掌握它。
提到迭代器,首先它是與集合相關的,集合也叫聚集、容器等,我們可以將集合看成是一個可以包容對象的容器,例如List,Set,Map,甚至數組都可以叫做集合,而迭代器的作用就是把容器中的對象一個一個地遍歷出來。
比如ArrayList是順序存儲結構,LinkedList是鏈式存儲結構,如果在外面對他進行遍歷,就需要知道他們里面的結構,然后依次訪問數據。如果有了迭代器,就可以保證能訪問元素同時不暴露結構。
主要使用在遍歷一個容器;其實就是對一個容器遍歷進行獨立;
例子:
老板需要每天需要知道每個部門人的信息,如果普通方式,就是對每個部門進行for循環,一次獲得信息;
用迭代器,老板只需要獲取每個部門的迭代器,就可以一次獲取的部門中的信息;如果增加或者減少部門也是只和迭代器有關;
角色
抽象容器(Aggregate ):
一般是一個接口,提供一個iterator()方法,例如java中的Collection接口,List接口,Set接口等。具體容器(ConcreteAggregate ):
就是抽象容器的具體實現類,比如List接口的有序列表實現ArrayList,List接口的鏈表實現LinkList,Set接口的哈希列表的實現HashSet等。抽象迭代器(Iterator ):
定義遍歷元素所需要的方法,一般來說會有這么三個方法:取得第一個元素的方法first(),取得下一個元素的方法next(),判斷是否遍歷結束的方法isDone()(或者叫hasNext()),移出當前對象的方法remove(),迭代器實現(ConcreteIterator ):
實現迭代器接口中定義的方法,完成集合的迭代。
實現代碼
Aggregate
interface Aggregate {
public void add(Object obj);
public void remove(Object obj);
public Iterator iterator();
}
ConcreteAggregate
class ConcreteAggregate implements Aggregate {
private List list = new ArrayList();
public void add(Object obj) {
list.add(obj);
}
public Iterator iterator() {
return new ConcreteIterator(list);
}
public void remove(Object obj) {
list.remove(obj);
}
}
Iterator
interface Iterator {
public Object next();
public boolean hasNext();
}
ConcreteIterator
class ConcreteIterator implements Iterator{
private List list = new ArrayList();
private int cursor =0;
public ConcreteIterator(List list){
this.list = list;
}
public boolean hasNext() {
if(cursor==list.size()){
return false;
}
return true;
}
public Object next() {
Object obj = null;
if(this.hasNext()){
obj = this.list.get(cursor++);
}
return obj;
}
}
Client
public class Client {
public static void main(String[] args){
Aggregate ag = new ConcreteAggregate();
ag.add("小明");
ag.add("小紅");
ag.add("小剛");
Iterator it = ag.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
}
}
上面的代碼中,Aggregate是容器類接口,大家可以想象一下Collection,List,Set等,Aggregate就是他們的簡化版,容器類接口中主要有三個方法:添加對象方法add、刪除對象方法remove、取得迭代器方法iterator。Iterator是迭代器接口,主要有兩個方法:取得迭代對象方法next,判斷是否迭代完成方法hasNext,大家可以對比java.util.List和java.util.Iterator兩個接口自行思考。
優缺點
優點:
簡化了遍歷方式,對于對象集合的遍歷,還是比較麻煩的,對于數組或者有序列表,我們尚可以通過游標來取得,但用戶需要在對集合了解很清楚的前提下,自行遍歷對象,但是對于hash表來說,用戶遍歷起來就比較麻煩了。而引入了迭代器方法后,用戶用起來就簡單的多了。
可以提供多種遍歷方式,比如說對有序列表,我們可以根據需要提供正序遍歷,倒序遍歷兩種迭代器,用戶用起來只需要得到我們實現好的迭代器,就可以方便的對集合進行遍歷了。
封裝性良好,用戶只需要得到迭代器就可以遍歷,而對于遍歷算法則不用去關心。
缺點:
對于比較簡單的遍歷(像數組或者有序列表),使用迭代器方式遍歷較為繁瑣,大家可能都有感覺,像ArrayList,我們寧可愿意使用for循環和get方法來遍歷集合。
適用場景
迭代器模式是與集合共生共死的,一般來說,我們只要實現一個集合,就需要同時提供這個集合的迭代器,就像java中的Collection,List、Set、Map等,這些集合都有自己的迭代器。假如我們要實現一個這樣的新的容器,當然也需要引入迭代器模式,給我們的容器實現一個迭代器。
但是,由于容器與迭代器的關系太密切了,所以大多數語言在實現容器的時候都給提供了迭代器,并且這些語言提供的容器和迭代器在絕大多數情況下就可以滿足我們的需要,所以現在需要我們自己去實踐迭代器模式的場景還是比較少見的,我們只需要使用語言中已有的容器和迭代器就可以了。