新聞中心
迭代器模式如何在java項目中實現(xiàn) ?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
創(chuàng)新互聯(lián)建站擁有十載的建站服務經驗,在此期間,我們發(fā)現(xiàn)較多的客戶在挑選建站服務商前都非常的猶豫。主要問題集中:在無法預知自己的網站呈現(xiàn)的效果是什么樣的?也無法判斷選擇的服務商設計出來的網頁效果自己是否會滿意?創(chuàng)新互聯(lián)建站業(yè)務涵蓋了互聯(lián)網平臺網站建設、移動平臺網站制作、網絡推廣、定制網站設計等服務。創(chuàng)新互聯(lián)建站網站開發(fā)公司本著不拘一格的網站視覺設計和網站開發(fā)技術相結合,為企業(yè)做網站提供成熟的網站設計方案。
java 迭代器模式實例詳解
首先,為什么使用迭代器模式,目的就是通過一個通用的迭代方法,隱藏stack,list,set以及數(shù)組中不同的遍歷細節(jié)。也就是說,我不想讓那些調用我的遍歷容器的方法的人知道我到底是怎么一個一個的獲取這些元素的(stack的pop,list的get,數(shù)組的array[i]),我只想讓他知道他能 通過一個迭代器Iterator或者通過一個for each語句就能拿到我容器里面所有的元素。這樣就能夠最大化的隱藏實現(xiàn)細節(jié),封裝變化了。
先通過一個例子來一步步了解這其中的重要性吧。比方說,我要開發(fā)一個平臺,這個平臺會獲取到京東的訂單和淘寶的訂單,然后把訂單中的所有購買條目全部打印出來。
既然要打印訂單中的所有條目,那么就得先知道這些條目,也就是訂單項有哪些屬性。
package iterator; /** * * @ClassName: Item * @Description: 訂單項 * @author minjun * */ public class Item { /**商品名稱*/ private String name; /**價格*/ private double price; /**描述*/ private String desc; /**數(shù)量*/ private int count; public Item(String name, double price, String desc, int count) { this.name = name; this.price = price; this.desc = desc; this.count = count; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } @Override public String toString() { return "Item [name=" + name + ", price=" + price + ", desc=" + desc + ", count=" + count + "]"; } }
知道了這個條目,然后我想看看京東和淘寶是如何存儲這些條目的。于是我問了問劉強東和馬云,得知京東是用集合List存儲,因為方便,而淘寶是用數(shù)組存儲,因為看起來更裝逼。他們都不愿意修改存儲的容器,因為改動太大。
這時, 如果用傳統(tǒng)想法,ok,我拿到京東的List,然后通過for循環(huán)和list.get(i)獲取里面的每個條目并打印。然后拿到淘寶的array,通過for循環(huán)和array[i]獲取里面的條目并打印。是不是可以實現(xiàn)呢?確實可以,但是我發(fā)現(xiàn)這樣的話,每個容器我都要實現(xiàn)一遍不同的打印方法。目前是兩個倒還好,如果又來個誰誰誰,用鏈表來實現(xiàn)容器,那我是不是又要新加一個迭代鏈表的方法呢?我當然不會愿意,因為這樣太麻煩了。于是乎,我有個想法,思路是這樣的:
我希望讓京東的訂單和淘寶的訂單都是可以方便的遍歷里面的元素,遍歷的方法能夠通過一個公共的方法來處理,而不是像之前那個分別做處理。根據這個思路,用TDD(測試驅動開發(fā))來做步驟實現(xiàn)。先寫好測試代碼,首先我要有個訂單接口,里面有兩個子類訂單(淘寶訂單和京東訂單):
package iterator; import org.junit.Test; public class TestCase { @Test public void test() { Order o = new TBOrder();//淘寶的訂單 // new JDOrder();//京東的訂單 printOrder(o);//打印訂單 } /**打印訂單 */ private void printOrder(Order o) { for (Item item : o) { System.out.println(item); } } }
如果能像上述這樣打印,那會多么方便啊。如果換成淘寶訂單,就用淘寶的訂單迭代實現(xiàn),換成京東的訂單,就用京東的訂單實現(xiàn),我在測試代碼根本不需要關注實現(xiàn)細節(jié)?,F(xiàn)在我會想,如果能通過什么方法直接打印這個訂單Order中的所有條目,那才能完整的實現(xiàn)我上述的代碼。也就是說我需要我的訂單是可以遍歷的,那應該怎么做呢?其實java中提供了這樣的接口,就是Iterable,如果我的訂單都實現(xiàn)了這個接口,那么我的訂單自然而然就可以通過一個for each循環(huán)來遍歷里面的內容。
/* * %W% %E% * * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang; import java.util.Iterator; /** Implementing this interface allows an object to be the target of * the "foreach" statement. * @since 1.5 */ public interface Iterable{ /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator iterator(); }
上面是java的Iterable接口,下面是我自己的訂單接口,繼承了Iterable接口
package iterator; public interface Order extends Iterable- { }
注意上面的Order訂單接口繼承了Iterable接口之后,同樣也繼承過來了一個抽象方法iterator。這個抽象方法才是Iterable的根本實現(xiàn)方案。我們會在子類訂單中分別實現(xiàn)這個接口,然后提供京東和淘寶不同的迭代方案。
京東
package iterator; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * * @ClassName: JDOrder * @Description: 京東訂單 * @author minjun * */ public class JDOrder implements Order { /** 京東用集合裝訂單項 */ private List- list = new ArrayList
- (); public JDOrder() { add("iphone6", 5000.00, "一部手機", 2); add("mbp", 16000.00, "一臺電腦", 1); add("西門子洗衣機", 3000.00, "一臺洗衣機", 3); } /** 添加訂單條目 */ public void add(String name, double price, String desc, int count) { list.add(new Item(name, price, desc, count)); } @Override public Iterator
- iterator() { return new MyIterator(); } private class MyIterator implements Iterator
- { private Iterator
- it = list.iterator(); @Override public boolean hasNext() { return it.hasNext(); } @Override public Item next() { return it.next(); } @Override public void remove() { throw new UnsupportedOperationException("目前不支持刪除操作"); } } }
淘寶
package iterator; import java.util.Iterator; import java.util.NoSuchElementException; /** * * @ClassName: TBOrder * @Description: 淘寶訂單 * @author minjun * */ public class TBOrder implements Order{ private int size=3; private Item[] orders=new Item[size]; private int index=0; public TBOrder(){ add("天貓1", 1111, "天貓活動1", 1); add("天貓2", 1111, "天貓活動1", 1); add("天貓3", 1111, "天貓活動1", 1); add("天貓4", 1111, "天貓活動1", 1); add("天貓5", 1111, "天貓活動1", 1); add("天貓6", 1111, "天貓活動1", 1); add("天貓7", 1111, "天貓活動1", 1); add("天貓8", 1111, "天貓活動1", 1); } /**添加訂單條目*/ public void add(String name, double price, String desc, int count) { //如果超過數(shù)組大小,就擴容 if(index>=size-1){ resize(); } orders[index++]=new Item(name, price, desc, count); } /**擴容*/ private void resize() { size=size<<1;//移位運算符--相當于size=size*2 Item[] newItems=new Item[size]; //將原始數(shù)組內容拷貝到新數(shù)組中去 for(int i=0;iiterator() { return new MyIterator(); } private class MyIterator implements Iterator - { private int curr=0; @Override public boolean hasNext() { return orders[curr]!=null; } @Override public Item next() { if(hasNext()){ return orders[curr++]; }else{ throw new NoSuchElementException("沒有這個元素"); } } @Override public void remove() { throw new UnsupportedOperationException("目前不支持刪除操作"); } } }
這樣,我就做到了提供一個標準的可以迭代的Order訂單接口,然后以兩種不同的迭代實現(xiàn)方案(京東、淘寶),為我們的測試類提供了一個可以屏蔽掉內部不同容器的具體實現(xiàn)區(qū)別。同時,這也是迭代器模式的運用。
總結:需求--不同容器不同迭代方案,改進--利用相同迭代方案來處理,將不同實現(xiàn)細節(jié)分別隱藏到容器自己的實現(xiàn)中。采用的方案就是實現(xiàn)Iterable接口,以及里面的Iterator方法,然后實現(xiàn)自己的迭代方式。
關于迭代器模式如何在java項目中實現(xiàn) 問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關知識。
分享標題:迭代器模式如何在java項目中實現(xiàn)
文章分享:http://www.dlmjj.cn/article/pdspgi.html