JAVA設計模式之 迭代器模式【Iterator Pattern】

一、概述

    提供一種方法來訪問聚合對象(容器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可以進行雙向遍歷(向前/向後),且可以在迭代期間修改列表。最後附上一張截圖如下:






發佈了71 篇原創文章 · 獲贊 16 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章