欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 迭代器模式實(shí)例詳解

 更新時(shí)間:2017年05月26日 15:40:49   作者:jonathan_loda  
這篇文章主要介紹了java 迭代器模式實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下

java 迭代器模式實(shí)例詳解

今天來(lái)818設(shè)計(jì)模式中的迭代器模式,也是java中Stack,List,Set等接口以及數(shù)組這個(gè)數(shù)據(jù)結(jié)構(gòu)都會(huì)使用的一種模式。

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

先通過(guò)一個(gè)例子來(lái)一步步了解這其中的重要性吧。比方說(shuō),我要開(kāi)發(fā)一個(gè)平臺(tái),這個(gè)平臺(tái)會(huì)獲取到京東的訂單和淘寶的訂單,然后把訂單中的所有購(gòu)買(mǎi)條目全部打印出來(lái)。

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

package iterator;

/**
 * 
* @ClassName: Item 
* @Description: 訂單項(xiàng)
* @author minjun
*
 */
public class Item {

 /**商品名稱(chēng)*/
 private String name;
 
 /**價(jià)格*/
 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 + "]";
 }
}

知道了這個(gè)條目,然后我想看看京東和淘寶是如何存儲(chǔ)這些條目的。于是我問(wèn)了問(wèn)劉強(qiáng)東和馬云,得知京東是用集合List存儲(chǔ),因?yàn)榉奖?,而淘寶是用?shù)組存儲(chǔ)。他們都不愿意修改存儲(chǔ)的容器,因?yàn)楦膭?dòng)太大。

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

我希望讓京東的訂單和淘寶的訂單都是可以方便的遍歷里面的元素,遍歷的方法能夠通過(guò)一個(gè)公共的方法來(lái)處理,而不是像之前那個(gè)分別做處理。根據(jù)這個(gè)思路,用TDD(測(cè)試驅(qū)動(dòng)開(kāi)發(fā))來(lái)做步驟實(shí)現(xiàn)。先寫(xiě)好測(cè)試代碼,首先我要有個(gè)訂單接口,里面有兩個(gè)子類(lèi)訂單(淘寶訂單和京東訂單):

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);
 }
 }
}

如果能像上述這樣打印,那會(huì)多么方便啊。如果換成淘寶訂單,就用淘寶的訂單迭代實(shí)現(xiàn),換成京東的訂單,就用京東的訂單實(shí)現(xiàn),我在測(cè)試代碼根本不需要關(guān)注實(shí)現(xiàn)細(xì)節(jié)?,F(xiàn)在我會(huì)想,如果能通過(guò)什么方法直接打印這個(gè)訂單Order中的所有條目,那才能完整的實(shí)現(xiàn)我上述的代碼。也就是說(shuō)我需要我的訂單是可以遍歷的,那應(yīng)該怎么做呢?其實(shí)java中提供了這樣的接口,就是Iterable,如果我的訂單都實(shí)現(xiàn)了這個(gè)接口,那么我的訂單自然而然就可以通過(guò)一個(gè)for each循環(huán)來(lái)遍歷里面的內(nèi)容。

/*
 * %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接口

package iterator;

public interface Order extends Iterable<Item>{

}

注意上面的Order訂單接口繼承了Iterable接口之后,同樣也繼承過(guò)來(lái)了一個(gè)抽象方法iterator。這個(gè)抽象方法才是Iterable的根本實(shí)現(xiàn)方案。我們會(huì)在子類(lèi)訂單中分別實(shí)現(xiàn)這個(gè)接口,然后提供京東和淘寶不同的迭代方案。

京東

package iterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 
 * @ClassName: JDOrder
 * @Description: 京東訂單
 * @author minjun
 * 
 */
public class JDOrder implements Order {

 /** 京東用集合裝訂單項(xiàng) */
 private List<Item> list = new ArrayList<Item>();

 public JDOrder() {
 add("iphone6", 5000.00, "一部手機(jī)", 2);
 add("mbp", 16000.00, "一臺(tái)電腦", 1);
 add("西門(mén)子洗衣機(jī)", 3000.00, "一臺(tái)洗衣機(jī)", 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("目前不支持刪除操作");
 }

 }
}

淘寶

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, "天貓活動(dòng)1", 1);
 add("天貓2", 1111, "天貓活動(dòng)1", 1);
 add("天貓3", 1111, "天貓活動(dòng)1", 1);
 add("天貓4", 1111, "天貓活動(dòng)1", 1);
 add("天貓5", 1111, "天貓活動(dòng)1", 1);
 add("天貓6", 1111, "天貓活動(dòng)1", 1);
 add("天貓7", 1111, "天貓活動(dòng)1", 1);
 add("天貓8", 1111, "天貓活動(dòng)1", 1);
 }
 
 /**添加訂單條目*/
 public void add(String name, double price, String desc, int count) {
 
 //如果超過(guò)數(shù)組大小,就擴(kuò)容
 if(index>=size-1){
  resize();
 }
  
 orders[index++]=new Item(name, price, desc, count);
 }
 
 /**擴(kuò)容*/
 private void resize() {
 size=size<<1;//移位運(yùn)算符--相當(dāng)于size=size*2
 Item[] newItems=new Item[size];
 //將原始數(shù)組內(nèi)容拷貝到新數(shù)組中去
 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("沒(méi)有這個(gè)元素");
  }
 }

 @Override
 public void remove() {
  throw new UnsupportedOperationException("目前不支持刪除操作");
 }
 
 }

}

這樣,我就做到了提供一個(gè)標(biāo)準(zhǔn)的可以迭代的Order訂單接口,然后以?xún)煞N不同的迭代實(shí)現(xiàn)方案(京東、淘寶),為我們的測(cè)試類(lèi)提供了一個(gè)可以屏蔽掉內(nèi)部不同容器的具體實(shí)現(xiàn)區(qū)別。同時(shí),這也是迭代器模式的運(yùn)用。

總結(jié):需求--不同容器不同迭代方案,改進(jìn)--利用相同迭代方案來(lái)處理,將不同實(shí)現(xiàn)細(xì)節(jié)分別隱藏到容器自己的實(shí)現(xiàn)中。采用的方案就是實(shí)現(xiàn)Iterable接口,以及里面的Iterator方法,然后實(shí)現(xiàn)自己的迭代方式。

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

相關(guān)文章

  • java——Byte類(lèi)/包裝類(lèi)的使用說(shuō)明

    java——Byte類(lèi)/包裝類(lèi)的使用說(shuō)明

    這篇文章主要介紹了java——Byte類(lèi)/包裝類(lèi)的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • springboot+Quartz實(shí)現(xiàn)任務(wù)調(diào)度的示例代碼

    springboot+Quartz實(shí)現(xiàn)任務(wù)調(diào)度的示例代碼

    本篇文章主要介紹了springboot + Quartz 實(shí)現(xiàn)任務(wù)調(diào)度的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • MyBatis逆向工程生成dao層增刪改查的操作

    MyBatis逆向工程生成dao層增刪改查的操作

    這篇文章主要介紹了MyBatis逆向工程生成dao層增刪改查的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中RedisUtils工具類(lèi)的使用

    Java中RedisUtils工具類(lèi)的使用

    本文主要介紹了Java中RedisUtils工具類(lèi)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java對(duì)象轉(zhuǎn)Json,關(guān)于@JSONField對(duì)象字段重命名和順序問(wèn)題

    Java對(duì)象轉(zhuǎn)Json,關(guān)于@JSONField對(duì)象字段重命名和順序問(wèn)題

    這篇文章主要介紹了Java對(duì)象轉(zhuǎn)Json,關(guān)于@JSONField對(duì)象字段重命名和順序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類(lèi)參數(shù)校驗(yàn)的方法

    SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類(lèi)參數(shù)校驗(yàn)的方法

    這篇文章主要介紹了SpringBoot使用validation-api實(shí)現(xiàn)對(duì)枚舉類(lèi)參數(shù)校驗(yàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實(shí)現(xiàn)

    mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實(shí)現(xiàn)

    XML 文件在解析時(shí)會(huì)將五種特殊字符進(jìn)行轉(zhuǎn)義,本文主要介紹了mybatis(mybatis-plus)映射文件(XML文件)中特殊字符轉(zhuǎn)義的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Java多線(xiàn)程volatile原理及用法解析

    Java多線(xiàn)程volatile原理及用法解析

    這篇文章主要介紹了Java多線(xiàn)程volatile原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java的回調(diào)機(jī)制實(shí)例詳解

    Java的回調(diào)機(jī)制實(shí)例詳解

    這篇文章主要介紹了Java的回調(diào)機(jī)制,結(jié)合實(shí)例形式詳細(xì)分析了java回調(diào)機(jī)制相關(guān)原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-08-08
  • Java中List轉(zhuǎn)Map的幾種常見(jiàn)方式與對(duì)比

    Java中List轉(zhuǎn)Map的幾種常見(jiàn)方式與對(duì)比

    JavaList轉(zhuǎn)Map是一個(gè)非常常用的技術(shù),對(duì)于Java開(kāi)發(fā)人員來(lái)講,掌握該技術(shù)可以幫助我們更加高效地操作List集合中的對(duì)象,這篇文章主要給大家介紹了關(guān)于Java中List轉(zhuǎn)Map的幾種常見(jiàn)方式與對(duì)比的相關(guān)資料,需要的朋友可以參考下
    2024-02-02

最新評(píng)論