一、概述
提供一種方法來訪問聚合對象(容器container),而不用暴露這個對象的內部細節。屬於對象行爲型模式。
二、適用場景
1>遍歷訪問聚合對象中的元素,而無須暴露它的內容表示,將聚合對象的訪問和內部數據的存儲分離。使得訪問聚合對象時無須瞭解其內部的實現細節。
2>需要爲一個聚合對象提供多種遍歷實現。
三、UML類圖
四、參與者
1>Iterator(抽象迭代器):它定義了訪問和遍歷元素的接口,聲明瞭用於遍歷數據元素的方法,例如:用於獲取第一個元素的first()方法,用於訪問下一個元素的next()方法,用於判斷是否還有下一個元素的hasNext()方法,用於獲取當前元素的currentItem()方法等,在具體迭代器中將實現這些方法。
2>ConcreteIterator(具體迭代器):它實現了抽象迭代器接口,完成對聚合對象的遍歷,同時在具體迭代器中通過遊標來記錄在聚合對象中所處的當前位置,在具體實現時,遊標通常是一個表示位置的非負整數。
3>Aggregate(抽象聚合類):它用於存儲和管理元素對象,聲明一個createIterator()方法用於創建一個迭代器對象,充當抽象迭代器工廠角色。
4>ConcreteAggregate(具體聚合類):它實現了在抽象聚合類中聲明的createIterator()方法,該方法返回一個與該具體聚合類對應的具體迭代器ConcreteIterator實例。
五、用例學習
1、抽象迭代器 Iterator.java
/**
* 自定義迭代器接口<br/>
* <b>說明:</b>
* 此處沒有使用JDK內置的迭代器接口 java.util.Iterator<E>
* @author [email protected]
*
*/
public interface Iterator {
/** 將遊標指向第一個元素 */
public Object first();
/** 將遊標指向下一個元素 */
public Object next();
/** 判斷是否存在下一個元素 */
public boolean hasNext();
/** 返回遊標指向的當前元素 */
public Object currentItem();
}
2、具體迭代器 ConcreteIterator.java
/**
* 具體迭代器實現類<br/>
* 訪問聚合對象、對聚合對象內部元素遍歷
* @author [email protected]
*
*/
public class ConcreteIterator implements Iterator {
// 維持一個對具體聚合對象的引用,以便於訪問存儲在聚合對象中的數據
private Aggregate aggregate;
// 定義一個遊標,用於記錄當前訪問位置
private int cursorIndex;
public ConcreteIterator(Aggregate aggregate){
this.aggregate = aggregate;
}
@Override
public Object first() {
cursorIndex = 0;
return aggregate.getObjects().get(cursorIndex);
}
@Override
public Object next() {
cursorIndex++ ;
if(hasNext()){
return aggregate.getObjects().get(cursorIndex);
}
return aggregate.getObjects().get(0);
}
@Override
public boolean hasNext() {
if (cursorIndex < aggregate.getObjects().size()) {
return true;
}
return false;
}
@Override
public Object currentItem() {
return aggregate.getObjects().get(cursorIndex);
}
}
3、抽象聚合類 Aggregate.java
import java.util.ArrayList;
import java.util.List;
/**
* 抽象聚合對象
* @author [email protected]
*
*/
public abstract class Aggregate {
/** 創建迭代器 具體創建什麼樣迭代方式的迭代器由具體的子類去實現 */
public abstract Iterator createIterator();
protected List<Object> objects = new ArrayList<Object>();
public Aggregate(List objects) {
this.objects = objects;
}
public void addObject(Object obj){
objects.add(obj);
}
public void deleteObject(Object obj){
objects.remove(obj);
}
public List<Object> getObjects(){
return objects;
}
}
4、具體聚合類 ConcreteAggregate.java
import java.util.List;
/**
* 具體聚合對象
* @author [email protected]
*
*/
public class ConcreteAggregate extends Aggregate {
public ConcreteAggregate(List objects) {
super(objects);
}
/**
* 提供工廠方法 創建具體的迭代器實例<br/>
* 由迭代器去執行具體的聚合對象的遍歷訪問<br/>
* 這樣就將聚合對象的數據存儲 和 對聚合對象元素的訪問進行了分離
*/
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
}
5、客戶端測試類 Client.java
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args){
List<String> nameList = new ArrayList<String>();
nameList.add("Java");
nameList.add("C");
nameList.add("C++");
// 實例化具體聚合對象 且 創建初始化集合數據
ConcreteAggregate languageAggregate = new ConcreteAggregate(nameList);
// 獲取聚合對象關聯的迭代器
Iterator iterator = languageAggregate.createIterator();
// 通過迭代器訪問聚合對象的內部數據
String firstLanguage = (String) iterator.first(); // 訪問聚合對象集合中索引爲1的元素
System.out.println(firstLanguage);
boolean hasNext = iterator.hasNext();
System.out.println("是否還有下一個元素:" + hasNext);
if(hasNext){
String nextLanguage = (String) iterator.next();
System.out.println("下一個元素:" + nextLanguage);
}
}
}
6、運行效果
Java
是否還有下一個元素:true
下一個元素:C
六、其他/擴展
Java JDK內置的迭代器:
說到迭代器模式 給我們的第一聯想就是Java中 我們使用最最頻繁的java.util.Iterator接口啦。
沒錯 他就是JDK中內置的迭代器。public interfaceIterator<E> 對collection進行迭代的迭代器。
這裏想擴展的一個點是:關於接口Iterator的子接口ListIterator<E>的介紹
這個ListIterator子接口 也許我們平時的代碼中使用的少,那麼他有什麼功能呢?
下面先看兩張截圖<比較比較 答案就在其中>
Iterator API方法:
ListIterator API方法:
從上面兩個截圖分析中我們可以看出Iterator只能進行單向遍歷,而ListIterator可以進行雙向遍歷(向前/向後),且可以在迭代期間修改列表。最後附上一張截圖如下: