一、迭代子(Iterator)模式的結構
迭代子模式可以順序訪問一個聚集中的元素而不必暴露聚集的內部表象。
所所示:
迭代子可分為外稟迭代子和內稟迭代子。
外稟迭代子適合於白箱聚集(白箱聚集就是向外界提供訪問自己內部元素介面的聚集),由於迭代的邏輯是由聚集對象本身提供的,所以這樣的外稟迭代子角色往往僅僅保持迭代的遊標位置。所以具體迭代子角色是一個外部類,它的建構函式接受一個具體聚集對象,從而可以調用這個聚集對象的迭代邏輯。
內稟迭代子適用於黑箱聚集(黑箱聚集不向外部提供遍曆自己元素對象的介面),由於黑箱聚集的元素對象只可以被聚集內部成員訪問,所以內稟迭代子只能是聚集內部的成員子類。
二、迭代子模式在java中的應用
在java聚集中的應用
在java.util.Collection介面提供iterator()Factory 方法返回一個Iterator類型對象,Collection介面的子類型AbstractList類的內部成員類Itr實現Iterator介面。所以Itr是內稟迭代子類,但是AbstractList也提供了自己的遍曆方法,所以它不是黑箱聚集,而是白箱聚集。其代碼如下:
import
java.util.Iterator;
public
interface Itr extends Iterator{
//再次調用next()方法時所用的指標
int cursor = 0;
//最近一次調用時所用的指標
int lastRet = -1;
int expectedModCount = modCount;
public boolean hasNext(){
return cursor!=size();
}
public Object next(){
try{
Object next =
get(cursor);
checkForComodification();
lastRet = cursor++;
return next;
}catch(IndexOutOfBoundsException
e){
checkForComodification();
throw new
NoSuchElementException();
}
}
//刪除最後遍曆過的元素,remove()方法只能刪除最後遍曆的元素
public void remove(){
if(lastRet ==-1)
throw new
IllegalStateException();
checkForComodification();
try{
AbstractList.this.remove(lastRet);
if(lastRet<cursor)
cursor--;
lastRet = -1;
expectedModCount =
modCount;
}catch(IndexOutOfBoundsException
e){
throw new
ConcurrentModificationException();
}
}
public void checkForComodification(){
if(modCount!=expectedModCount)
throw new
ConcurrentModificationException();
}
}
其中的modCount、get(cursor)等變數和方法均是AbstractList類所擁有,Itr可以直接使用。方法checkForComodification()會檢查聚集的內容是否剛剛被外界直接修改過(不是通過迭代子提供的remove()方法修改的)。如果在迭代子開始後,聚集的內容被外界繞過迭代子物件而直接修改過年話,這個方法立即拋出異常。
另外:AbstractList類也提供了listIterator()方法,返回一個實現了Listiterator介面的類ListItr執行個體。ListIterator介面實現了正向迭代和逆向迭代,同時還提供了在迭代過程當中安全修改列的內容的方法。
Enumeration與Iterator的區別:(1)Enumeration沒有remove方法(2)Enumeration是在Vector中的element()方法中作用一個無名類實現的,它不支付Fail Fast,也就是說在迭代過程中,聚集對象被外界意外直接修改,則這個迭代過程還會立即捕獲任何異常。