lecture12-Iterator.ppt_第1頁
lecture12-Iterator.ppt_第2頁
lecture12-Iterator.ppt_第3頁
lecture12-Iterator.ppt_第4頁
lecture12-Iterator.ppt_第5頁
已閱讀5頁,還剩32頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、第12章 Iterator-迭代器,第12章 Iterator-迭代器,辛國棟 研究院529,5687921,第12章 Iterator-迭代器,管理良好的集合,有許多種方法可以把對象堆起來成為一個集合(Collection) 數(shù)組 列表 散列表 Etc 客戶總要對集合進(jìn)行遍歷,而當(dāng)他這么做的時候,你打算讓客戶看到你是用什么結(jié)構(gòu)實(shí)現(xiàn)嗎? 本章學(xué)習(xí)如何讓客戶遍歷你的對象而又無法窺視存儲對象的方式,第12章 Iterator-迭代器,有關(guān)美食,第12章 Iterator-迭代器,問題提出,有一個餐廳和一個煎餅屋強(qiáng)強(qiáng)聯(lián)合,形成一個大餐廳 原餐廳-提供午餐 原煎餅屋-提供早餐 這樣可以在同一個地方享用

2、美味的煎餅早餐和好吃的午餐了。雙方達(dá)成協(xié)議,早餐用原來的煎餅屋菜單,午餐用餐廳的菜單。 但是有點(diǎn)麻煩 煎餅屋用ArrayList記錄菜單而餐廳用的是Array來記錄菜單。 雙方都不愿意更改記錄方式,因?yàn)槊總€餐廳對菜單的依賴太多了。,第12章 Iterator-迭代器,檢查菜單項(xiàng),餐廳菜單 素食BLT $2.99 煎培根、生菜 String description; boolean vegetarian; double price; public MenuItem(String name,String description,boolean vegetarian,double price) th

3、 = name; this.price = price; this.vegetarian = vegetarian; this.description = description; public String getDescription() return description; public String getName() return name; public double getPrice() return price; public boolean isVegetarian() return vegetarian; ,第12章 Iterator-迭代器,煎餅屋菜單Pa

4、ncakeHouseMenu,public class PancakeHouseMenu ArrayList menuItems; public PancakeHouseMenu() menuItems = new ArrayList(); addItem(K / other menu methods here ,第12章 Iterator-迭代器,餐廳菜單DinerMenu,public class DinerMenu implements Menu static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem menuIte

5、ms; public DinerMenu() menuItems = new MenuItemMAX_ITEMS; addItem(Vegetarian BLT,(Fakin) Bacon with lettuce / other menu methods here ,第12章 Iterator-迭代器,Your job:,兩種不同的菜單表現(xiàn)方式會讓事情變得復(fù)雜。 假設(shè)你被合組的公司雇用,你的工作是建立一個java版本的“女招待” 這個女招待的規(guī)格是: 能對顧客的需求打印定制菜單 甚至告訴顧客是否某個菜單項(xiàng)是素食的而不必詢問廚師。,Java版本的女招待,代號“Alice” printMenu(

6、) 打印出菜單上的每一項(xiàng) printBreakfastMenu() 只打印早餐項(xiàng) printLunchMenu() 只打印午餐項(xiàng) printVegetarianMenu() 打印所有的素食菜單項(xiàng) isItemVegetarian(name) 指定項(xiàng)的名稱,如何是素食,返回true,否則返回false,第12章 Iterator-迭代器,Your job 從printMenu()開始,打印每份菜單上的所有項(xiàng),必須調(diào)用PancakeHouseMenu和DinerMenu的getMenuItems ()方法,來得到它們各自的菜單項(xiàng),注意兩者的返回類型是不一樣的。 /取得煎餅屋菜單項(xiàng) PancakeH

7、ouseMenu pancakeHouseMenu=new PancakeHouseMenu(); ArrayList breakfastItems = pancakeHouseMenu.getMenuItems(); /取得餐廳菜單項(xiàng) DinerMenu dinerMenu = new DinerMenu(); MenuItem lunchItems = dinerMenu.getMenuItems();,第12章 Iterator-迭代器,Your job 從printMenu()開始,用循環(huán)把菜單項(xiàng)列出 /煎餅屋菜單項(xiàng) for(int i=0;ibreakfastitems.size()

8、;i+) MenuItem menuItem =(MenuItem) breakfastitems.get(i); System.out.print(menuItem.getName()+ “ ”); System.out.print(menuItem.getPrice()+“ ”); System.out.print(menuItem.getDescription()+“ ”); /餐廳菜單項(xiàng) for(int i=0;ilunchItems.size();i+) MenuItem menuItem lunchItemsi; System.out.print(menuItem.getName(

9、)+ “ ”); System.out.print(menuItem.getPrice()+“ ”); System.out.print(menuItem.getDescription()+“ ”); ,第12章 Iterator-迭代器,Your job 從printMenu()開始,實(shí)現(xiàn)其他方法 發(fā)現(xiàn)總是需要處理兩個菜單,并且用兩個循環(huán)遍歷這些項(xiàng) 如何有第三家餐廳以不同實(shí)現(xiàn)出現(xiàn),就需要三個循環(huán)。,第12章 Iterator-迭代器,Whats next?,煎餅屋和餐廳都不想改變自身實(shí)現(xiàn),因?yàn)橐馕吨獙懺S多代碼。 如何他們不肯退讓,我們寫出來的“女招待”代碼將難以維護(hù)。 考慮前面的例子,如何

10、處理這個難題? 找出一個方法,讓他們的菜單實(shí)現(xiàn)一個相同的接口 這樣可以最小化女招待的代碼的具體引用 有希望擺脫遍歷這兩個菜單所需要的多個循環(huán),第12章 Iterator-迭代器,找出變化點(diǎn),封裝之!,找出變化點(diǎn),where? 女招待的變化點(diǎn)在于由不同的集合類型所造成的遍歷。 要遍歷早餐,需要ArrayList的size()和get()方法 for(int i=0;ibreakfastitems.size();i+) MenuItem menuItem =(MenuItem) breakfastitems.get(i); ,get(0),get(1),get(2),get(3),get()方法讓

11、我們遍歷每個項(xiàng),第12章 Iterator-迭代器,找出變化點(diǎn),封裝之!,找出變化點(diǎn),where? 女招待的變化點(diǎn)在于由不同的集合類型所造成的遍歷。 要遍歷早餐,需要ArrayList的size()和get()方法 for(int i=0;ilunchItems.length;i+) MenuItem menuItem =lunchItemsi; ,lunchItems0,lunchItems1,lunchItems2,lunchItems3,使用數(shù)組下標(biāo)的方法來遍歷,第12章 Iterator-迭代器,對arryList和arry操作的討論,要遍歷菜單,所以必須對arraylist和arra

12、y分別操作 現(xiàn)在是對具體編程,所以可以對此進(jìn)行優(yōu)化,how? your solution? 可否將arrylist和array向上做一個抽象? 答案是肯定的,那就是iterator,第12章 Iterator-迭代器,使用迭代器對變化進(jìn)行封裝,創(chuàng)建一個迭代器(iterator),利用它來封裝“遍歷集合內(nèi)每個對象的過程” Iterator iterator = breakfastMenu.createIterator(); while(iterator.hasNext() MenuItem menuItem =(MenuItem)iterator.next() ,get(0),get(1),ge

13、t(2),get(3),next(),客戶只需要調(diào)動hasNext()和next();而迭代器會暗中調(diào)有ArrayList的get()方法,第12章 Iterator-迭代器,使用迭代器對變化進(jìn)行封裝,在數(shù)組上試試 Iterator iterator = lunchMenu.createIterator(); while(iterator.hasNext() MenuItem menuItem =(MenuItem)iterator.next() ,next(),客戶只需要調(diào)動hasNext()和next(); 而迭代器會暗中調(diào)有數(shù)組的下標(biāo),第12章 Iterator-迭代器,Now,焦點(diǎn)轉(zhuǎn)移

14、到Iterator!,客戶只需要調(diào)動hasNext()和next(),而迭代器會暗中調(diào)有數(shù)組的下標(biāo)或者ArrayList的get()方法,這樣解決了兩者抽象問題? Iterator又是如何實(shí)現(xiàn)以上功能的呢? “客戶只需要調(diào)動hasNext()和next().”(省略n多廢話) Its a interface. So, it should have hasNext() and next() method,第12章 Iterator-迭代器,Iterator接口應(yīng)該是這個樣子:,hasNext()方法告訴我們是否在這個集合中還有更多的元素,Next()方法返回這個集合中的下一個對象,public

15、interface Iterator boolean hasNext(); Object next(); ,第12章 Iterator-迭代器,Iterator功能總結(jié),“集合”(collection)是指一群對象,其存儲方式可以各種數(shù)據(jù)結(jié)構(gòu),無論是什么方式存儲,都認(rèn)為是集合,有時候也稱為聚合aggregate。 一旦我們有了這個接口,就可以為各種對象集合實(shí)現(xiàn)迭代器:數(shù)組、列表、散列 實(shí)現(xiàn)了迭代器后,我們只需要hasNext()判斷有沒有對象數(shù)據(jù)了,然后next()取對象即可。,第12章 Iterator-迭代器,構(gòu)建餐廳菜單迭代器,public class DinerMenuIterator

16、 implements Iterator MenuItem items; int position = 0; /記錄當(dāng)前數(shù)組遍歷的位置 public DinerMenuIterator(MenuItem items) this.items = items; public Object next() MenuItem menuItem = itemsposition; position = position + 1; return menuItem; public boolean hasNext() if (position = items.length | itemsposition = nu

17、ll) return false; else return true; ,第12章 Iterator-迭代器,餐廳菜單DinerMenu(最初版本),public class DinerMenu implements Menu static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem menuItems; public DinerMenu() menuItems = new MenuItemMAX_ITEMS; addItem(Vegetarian BLT,(Fakin) Bacon with lettuce / other

18、 menu methods here ,第12章 Iterator-迭代器,餐廳菜單DinerMenu改造,public class DinerMenu static final int MAX_ITEMS = 6; int numberOfItems = 0; MenuItem menuItems; /構(gòu)造函數(shù)在這 /additem方法在這 /* public MenuItem getMenuItems() return menuItems; */ /添加如下代碼 public Iterator createrIterator() return new DinnerMenuIterator(

19、menuItems); / other menu methods here ,第12章 Iterator-迭代器,修正女招待的代碼,public class Waitress PancakeHouseMenu pancakeHouseMenu; DinerMenu dinerMenu; public Waitress(PancakeHouseMenu pancakeHouseMenu, DinerMenu dinerMenu) this.pancakeHouseMenu = pancakeHouseMenu; this.dinerMenu = dinerMenu; public void pr

20、intMenu() Iterator pancakeIterator = pancakeHouseMenu.createIterator(); Iterator dinerIterator = dinerMenu.createIterator(); System.out.println(MENUn-nBREAKFAST); printMenu(pancakeIterator); System.out.println(nLUNCH); printMenu(dinerIterator); private void printMenu(Iterator iterator) while (iterat

21、or.hasNext() MenuItem menuItem = (MenuItem)iterator.next(); System.out.print(menuItem.getName() + , ); System.out.print(menuItem.getPrice() + - ); System.out.println(menuItem.getDescription(); /省略其他的方法 ,第12章 Iterator-迭代器,測試我們的代碼,public class MenuTestDrive public static void main(String args) /建立兩個菜單

22、對象 PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); DinerMenu dinerMenu = new DinerMenu(); /創(chuàng)建女招待,然后把菜單傳遞給她 Waitress waitress = new Waitress(pancakeHouseMenu, dinerMenu); /女招待報菜單 waitress.printMenu(); ,第12章 Iterator-迭代器,測試結(jié)果,第12章 Iterator-迭代器,喘口氣,煎餅屋和餐廳合并但是菜單實(shí)現(xiàn)方式不同,讓女招待能應(yīng)對顧客需求打印菜單,每個菜單都有一

23、套循環(huán)遍歷菜單,女招待被捆綁于具體類menuItem和ArrayList,對具體類進(jìn)行封裝,引入Iterator,菜單的實(shí)現(xiàn)被封裝,女招待不知道菜單如何存儲菜單項(xiàng),只要實(shí)現(xiàn)迭代器,女招待只需要一個循環(huán)就可以多態(tài)處理任何項(xiàng)的集合,現(xiàn)在的菜單接口完全一樣,但是,哎呀,我們還是沒有一個共同的接口,也就是說女招待仍然捆綁于兩個具體的菜單類:,Waitress waitress =new Waitress(pancakeHouseMenu, dinerMenu);,第12章 Iterator-迭代器,目前的設(shè)計類圖,iterator,+ hasNext(),+ next(),第12章 Iterator-

24、迭代器,improved version,第12章 Iterator-迭代器,java.util.iterator,iterator,+ hasNext(),+ next(),hasNext()方法告訴我們是否在這個集合中還有更多的元素,Next()方法返回這個集合中的下一個對象,+ remove(),允許刪除由next()方法返回的最后一項(xiàng),ArrayList有Iterator接口,而數(shù)組沒有,因此用java的iterator仍然需要實(shí)現(xiàn)一個迭代器,第12章 Iterator-迭代器,PancakeMenu改造,因?yàn)閖ava已經(jīng)實(shí)現(xiàn)了迭代器,并且該Menu是用ArrayList設(shè)計的,故可以

25、刪除PancakeMenuIterator類(由ArrayList實(shí)現(xiàn)的Itrator替換),引入java.util.Iterator;改變下面一行代碼 public Iterator createIterator() return menuItem.iterator(); ,第12章 Iterator-迭代器,DinerMenu,import java.util.Iterator; public class DinerMenuIterator implements Iterator MenuItem list; int position = 0; public DinerMenuIterat

26、or(MenuItem list) this.list = list; public Object next() MenuItem menuItem = listposition; position = position + 1; return menuItem; public boolean hasNext() if (position = list.length | listposition = null) return false; else return true; public void remove() if (position = 0) throw new IllegalStateException (You cant remove an item until youve done at least one next(); if (listposition-1 != null) for (int i = posi

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論