任何容器類,都必須有某種方式可以插入元素並將它們再次取出,畢竟持有事物是容器最基本的工作,對於List,add()插入fang,get()取出,如果從更高層的角度思考,會發現這里有個確定:要用容器,必須對容器的確切類型編程,這樣如果原本是List編碼的,但是后來要應用於Set,那么此時該怎么辦,是重寫通用代碼還是如何
迭代器(也是一種設計模式)的概念可用於達成這個目的,迭代器是一個對象,它的工作是遍歷並選擇序列中 對象,而客服端程序員不必關心或知道該序列的底層結構,此外迭代器通常被稱為輕量級對象:創建它的代價很小. 因此經常可以見到對迭代器有些奇怪的限制;例如,Java的Iterator只能單向移動,這個Iterator只能用來:
1)使用方法iterator()要求容器返回一個Iterator. Iterator將准備好返回序列的第一個元素
2)使用next()獲得序列中的下一個元素
3)使用hasNext()檢查序列中是否還有元素
4)使用remove()將迭代器新近返回的元素刪除 (必須先調用next())
package java.util; import java.util.function.Consumer; public interface Iterator<E> { boolean hasNext(); //檢查是否有下一個元素 E next(); //返回下一個元素 default void remove() { //移除一個elment throw new UnsupportedOperationException("remove"); } default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
//: holding/SimpleIteration.java package object; import typeinfo.pets.*; import java.util.*; public class SimpleIteration { public static void main(String[] args) { List<Pet> pets = Pets.arrayList(12); Iterator<Pet> it = pets.iterator(); while(it.hasNext()) { Pet p = it.next(); System.out.print(p.id() + ":" + p + " "); } System.out.println(); // A simpler approach, when possible: for(Pet p : pets) System.out.print(p.id() + ":" + p + " "); System.out.println(); // An Iterator can also remove elements: it = pets.iterator(); for(int i = 0; i < 6; i++) { it.next(); it.remove(); } System.out.println(pets); } } /* Output: 0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster 0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 8:Cymric 9:Rat 10:EgyptianMau 11:Hamster [Pug, Manx, Cymric, Rat, EgyptianMau, Hamster] *///:~
接受對象容器並傳遞它,從而在每個對象上都執行操作,這種思想十分強大,現在創建一個display()方法,它不必知道容器的確切類型,清注意diplay()不包含任何有關它所遍歷的序列的類型信息,而這也展示了Iterator的真正威力: 能夠將遍歷序列的操作與序列底層的結構分離,正由於此,我們有時會說,迭代器統一了對容器的訪問方式
//: holding/CrossContainerIteration.java package object; import typeinfo.pets.*; import java.util.*; public class CrossContainerIteration { public static void display(Iterator<Pet> it) { while(it.hasNext()) { Pet p = it.next(); System.out.print(p.id() + ":" + p + " "); } System.out.println(); } public static void main(String[] args) { ArrayList<Pet> pets = Pets.arrayList(8); LinkedList<Pet> petsLL = new LinkedList<Pet>(pets); HashSet<Pet> petsHS = new HashSet<Pet>(pets); TreeSet<Pet> petsTS = new TreeSet<Pet>(pets); display(pets.iterator()); display(petsLL.iterator()); display(petsHS.iterator()); display(petsTS.iterator()); } } /* Output: 0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 0:Rat 1:Manx 2:Cymric 3:Mutt 4:Pug 5:Cymric 6:Pug 7:Manx 4:Pug 6:Pug 3:Mutt 1:Manx 5:Cymric 7:Manx 2:Cymric 0:Rat 5:Cymric 2:Cymric 7:Manx 1:Manx 3:Mutt 6:Pug 4:Pug 0:Rat *///:~