(參考自設計模式)
在設計程式的過程中,經常有的需求之一,就是希望逐一取得某物件內部的所有資料(或物件),像是取得ArrayList中所有 的資料,或取得HashSet中所有的資料。
由於物件在實作內部資料的組織時方式不盡相同,因此也只有物件本身才知道如何收集內部資料,因此Iterator的實作,通常會是物件的內部類別,外界無 需關心,只要知道如何操作Iterator即可。
以Java 的Collection API設計來說
在JDK 1.4時,iterator()方法是定義在Collection介面上,每個Collection的實現類別,都會有iterator()方法,在 JDK5之後,則將iterator()方法定義在Iterable介面上,而Collection介面則繼承了Iterable介面:
例如,您也許會希望設計一個foreach方法,可以將丟給它的物件中的資料逐一取得並顯示在主控台中:
Listlist = new ArrayList ();...foreach(list);Set set = new HashSet ();....foreach(set);
因為List是有序結構並有索引特性,而Set則為無序不重複的特性,兩者所提供的公開存取方法也不相同,如何將foreach方法設計的通用是個問題。
無論是List或Set,都有個iterator()方法可以傳回一個Iterator物件,這個物件會收集List或Set物件內部資料,並有 hasNext()、next()方法可以使用,而實際上,這個方法是繼承自Collection介面(List與Set的父介面),您可以這麼設計 foreach方法:
public static void foreach(Collectioncollection) { Iterator iterator = collection.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }}
這是Iterator模式的實現,不同的物件內部在組織資料方式並不相同(陣列?鏈結?雜湊?),所提供的公開存取介面也不一樣,為了有一致的方式來逐一取 得物件內部的資料,您可以讓一個Iterator於物件內部進行收集,之後傳回Iterator物件,透過該Iterator來逐一取得物件內部資料。
其他語言的一些iterator的範例:
C#
// Method that takes an iterable input (possibly an array)// and returns all even numbers.public static IEnumerableGetEven(IEnumerable numbers){ foreach(int i in numbers) { if (i % 2 == 0) yield return i; }}
C++
templatevoid printall(InputIterator first, InputIterator last){ for(; first != last; ++first) { std::cout << *first << std::endl; }}
JAVA:
Iterator iter = list.iterator();//Iteratoriter = list.iterator(); in J2SE 5.0while (iter.hasNext()) System.out.println(iter.next());
PHP
class a implements Iterator { var $keys = array("k1", "k2", "k3"); var $vals = array("v1", "v2", "v3"); var $pos = 0; function current() { return $this->vals[$this->pos]; } function key() { return $this->keys[$this->pos]; } function next() { $this->pos++; } function rewind() { $this->pos = 0; } function valid() { if($this->pos>=count($this->keys)) { return false; } else { return true; } }}$a = new a;foreach($a as $k=>$v) echo "$k:::$v\n";執行結果:Feng-Hsu-Pingteki-MacBook-Air:ironman6 fillano$ php 1-4a.phpk1:::v1k2:::v2k3:::v3
沒有留言:
張貼留言