一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java 迭代器模式實例詳解

java 迭代器模式實例詳解

2020-10-30 23:35jonathan_loda Java教程

這篇文章主要介紹了java 迭代器模式實例詳解的相關資料,需要的朋友可以參考下

java 迭代器模式實例詳解

今天來818設計模式中的迭代器模式,也是java中Stack,List,Set等接口以及數組這個數據結構都會使用的一種模式。

首先,為什么使用迭代器模式,目的就是通過一個通用的迭代方法,隱藏stack,list,set以及數組中不同的遍歷細節。也就是說,我不想讓那些調用我的遍歷容器的方法的人知道我到底是怎么一個一個的獲取這些元素的(stack的pop,list的get,數組的array[i]),我只想讓他知道他能 通過一個迭代器Iterator或者通過一個for each語句就能拿到我容器里面所有的元素。這樣就能夠最大化的隱藏實現細節,封裝變化了。

先通過一個例子來一步步了解這其中的重要性吧。比方說,我要開發一個平臺,這個平臺會獲取到京東的訂單和淘寶的訂單,然后把訂單中的所有購買條目全部打印出來。

既然要打印訂單中的所有條目,那么就得先知道這些條目,也就是訂單項有哪些屬性。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package iterator;
 
/**
 *
* @ClassName: Item
* @Description: 訂單項
* @author minjun
*
 */
public class Item {
 
 /**商品名稱*/
 private String name;
 
 /**價格*/
 private double price;
 
 /**描述*/
 private String desc;
 
 /**數量*/
 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存儲,因為方便,而淘寶是用數組存儲,因為看起來更裝逼。他們都不愿意修改存儲的容器,因為改動太大。

這時, 如果用傳統想法,ok,我拿到京東的List,然后通過for循環和list.get(i)獲取里面的每個條目并打印。然后拿到淘寶的array,通過for循環和array[i]獲取里面的條目并打印。是不是可以實現呢?確實可以,但是我發現這樣的話,每個容器我都要實現一遍不同的打印方法。目前是兩個倒還好,如果又來個誰誰誰,用鏈表來實現容器,那我是不是又要新加一個迭代鏈表的方法呢?我當然不會愿意,因為這樣太麻煩了。于是乎,我有個想法,思路是這樣的:

我希望讓京東的訂單和淘寶的訂單都是可以方便的遍歷里面的元素,遍歷的方法能夠通過一個公共的方法來處理,而不是像之前那個分別做處理。根據這個思路,用TDD(測試驅動開發)來做步驟實現。先寫好測試代碼,首先我要有個訂單接口,里面有兩個子類訂單(淘寶訂單和京東訂單):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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);
 }
 }
}

如果能像上述這樣打印,那會多么方便啊。如果換成淘寶訂單,就用淘寶的訂單迭代實現,換成京東的訂單,就用京東的訂單實現,我在測試代碼根本不需要關注實現細節。現在我會想,如果能通過什么方法直接打印這個訂單Order中的所有條目,那才能完整的實現我上述的代碼。也就是說我需要我的訂單是可以遍歷的,那應該怎么做呢?其實java中提供了這樣的接口,就是Iterable,如果我的訂單都實現了這個接口,那么我的訂單自然而然就可以通過一個for each循環來遍歷里面的內容。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * %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<T> {
 
  /**
   * Returns an iterator over a set of elements of type T.
   *
   * @return an Iterator.
   */
  Iterator<T> iterator();
}

上面是java的Iterable接口,下面是我自己的訂單接口,繼承了Iterable接口

?
1
2
3
4
5
package iterator;
 
public interface Order extends Iterable<Item>{
 
}

注意上面的Order訂單接口繼承了Iterable接口之后,同樣也繼承過來了一個抽象方法iterator。這個抽象方法才是Iterable的根本實現方案。我們會在子類訂單中分別實現這個接口,然后提供京東和淘寶不同的迭代方案。

京東

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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<Item> list = new ArrayList<Item>();
 
 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<Item> iterator() {
 return new MyIterator();
 }
 
 private class MyIterator implements Iterator<Item> {
 
 private Iterator<Item> it = list.iterator();
 
 @Override
 public boolean hasNext() {
  return it.hasNext();
 }
 
 @Override
 public Item next() {
  return it.next();
 }
 
 @Override
 public void remove() {
  throw new UnsupportedOperationException("目前不支持刪除操作");
 }
 
 }
}

淘寶

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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) {
 
 //如果超過數組大小,就擴容
 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];
 //將原始數組內容拷貝到新數組中去
 for(int i=0;i<orders.length;i++){
  newItems[i]=orders[i];
 }
 orders=newItems;
 }
 
 @Override
 public Iterator<Item> iterator() {
 return new MyIterator();
 }
 
 private class MyIterator implements Iterator<Item>{
 
 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訂單接口,然后以兩種不同的迭代實現方案(京東、淘寶),為我們的測試類提供了一個可以屏蔽掉內部不同容器的具體實現區別。同時,這也是迭代器模式的運用。

總結:需求--不同容器不同迭代方案,改進--利用相同迭代方案來處理,將不同實現細節分別隱藏到容器自己的實現中。采用的方案就是實現Iterable接口,以及里面的Iterator方法,然后實現自己的迭代方式。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩在线观看精品 | 国产精彩视频 | 九九热国产视频 | 日韩美毛片 | 91韩国女主播 | 白丝美女同人18漫画 | 欧美久在线观看在线观看 | 久久亚洲精品中文字幕60分钟 | 亚洲视频在线一区二区三区 | 精品国产美女福利在线 | 91短视频在线观看2019 | 欧美极品摘花过程 | 国产一区二区精品久 | 青青草原伊人网 | 美女被绑着吸下部的故事 | 四虎精品免费国产成人 | japanhd粗暴video | 久久精品18| 含羞草传媒每天免费一次破解 | 亚洲免费视频在线 | 国产成人精品曰本亚洲78 | 久久噜国产精品拍拍拍拍 | 久久热国产在线视频 | 国产亚洲欧美日韩综合综合二区 | 太深了 太粗h1v1 | 第一福利在线视频 | 高跟丝袜麻麻求我调教 | 欧美一区二区三区精品影视 | 小草高清视频免费直播 | 91夜色视频 | 日本视频在线免费观看 | 婷婷综合久久中文字幕 | 人人人人看人人人做人人 | 欧美亚洲天堂网 | 波多野结衣 在线 | 四虎影院大全 | 香港三级浴室女警官 | 窝窝午夜理伦影院 | 亚洲入口| jzzjzz视频免费播放 | 亚洲无线一二三四区 |