国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android編程設計模式之迭代器模式詳解

2019-10-22 18:18:35
字體:
來源:轉載
供稿:網(wǎng)友

本文實例講述了Android編程設計模式之迭代器模式。分享給大家供大家參考,具體如下:

一、介紹

迭代器模式(Iterator Pattern)又稱為游標(Cursor)模式,是行為型設計模式之一。迭代器模式算是一個比較古老的設計模式,其源于對容器的訪問,比如Java中的List、Map、數(shù)組等,我們知道對容器對象的訪問必然會涉及遍歷算法,我們可以將遍歷的方法封裝在容器中,或者不提供遍歷方法。如果我們將遍歷的方法封裝到容器中,那么對于容器類來說就承擔了過多的功能,容器類不僅要維護自身內(nèi)部的數(shù)據(jù)元素而且還要對外提供遍歷的接口方法,因為遍歷狀態(tài)的存儲問題還不能對同一個容器同時進行多個遍歷操作,如果我們不提供遍歷方法而讓使用者自己去實現(xiàn),又會讓容器的內(nèi)部細節(jié)暴露無遺,正因于此,迭代模式應運而生,在客戶訪問類與容器體之間插入了一個第三者——迭代器,很好地解決了上面所述的弊端。

二、定義

提供一種方法順序訪問一個容器對象中的各個元素,而又不需要暴露該對象的內(nèi)部表示。

三、使用場景

遍歷一個容器對象。

四、迭代器模式的UML類圖

UML類圖:

Android,設計模式,迭代器模式

通用模式代碼:

迭代器接口:

public interface Iterator<T> {  /**   * 是否還有下一個元素   * @return true表示有,false表示沒有   **/  boolean hasNext();  /**   * 返回當前位置的元素并將位置移至下一位   **/  T next();}

具體迭代器類:

public class ConcreteIterator<T> implements Iterator<T>{  private List<T> list;  private int cursor = 0;  public ConcreteIterator(List<T> list) {    this.list = list;  }  @Override  public boolean hasNext() {    return cursor != list.size();  }  @Override  public T next() {    T obj = null;    if (this.hasNext()) {      obj = this.list.get(cursor++);    }    return obj;  }}

容器接口:

public interface Aggregation<T> {  /**   * 添加一個元素   **/  void add(T obj);  /**   * 移除一個元素   **/  void remove(T obj);  /**   * 獲取容器的迭代器   **/  Iterator<T> iterator();}

具體容器類:

public class ConcreteAggregation<T> implements Aggregation<T>{  private List<T> list = new ArrayList<>();  @Override  public void add(T obj) {    list.add(obj);  }  @Override  public void remove(T obj) {    list.remove(obj);  }  @Override  public Iterator<T> iterator() {    return new ConcreteIterator<>(list);  }}

客戶類:

public class Client {  public static void main(String args[]) {    Aggregation<String> a = new ConcreteAggregation<>();    a.add("a");    a.add("b");    a.add("c");    Iterator<String> iterator = a.iterator();    while (iterator.hasNext()) {      System.out.print(iterator.next());    }  }}

角色介紹:

Iterator:迭代器接口,迭代器接口負責定義、訪問和遍歷元素的接口。

ConcreteIterator:具體迭代器類,具體迭代器類的目的主要是實現(xiàn)迭代器接口,并記錄遍歷的當前位置。

Aggregate:容器接口,容器接口負責提供創(chuàng)建具體迭代器角色的接口。

ConcreteAggregate:具體容器類,具體迭代器角色與該容器相關聯(lián)。

Client:客戶類。

五、簡單實現(xiàn)

小民和小輝分別在公司的兩個事業(yè)部,某天老板安排任務讓他們倆統(tǒng)計一下各自部門的員工數(shù)據(jù),這很好辦嘛,建一個類用數(shù)據(jù)結構把所有員工數(shù)據(jù)存進去即可,老板要看的時候給他用for循環(huán)實現(xiàn),還是比較容易的,下面就先為員工創(chuàng)建一個實體類:

員工實體類:

public class Employee {  private String name;// 姓名  private int age;// 年齡  private String sex;// 性別  private String position;// 職位  public Employee(String name, int age, String sex, String position) {    super();    this.name = name;    this.age = age;    this.sex = sex;    this.position = position;  }  // 簡化代碼,省略setter和getter方法  @Override  public String toString() {    return "Employee{" + "name='" + name + '/'' + ", age=" + age + ", sex="        + sex + ", position='" + position + '/'' + "}";  }}

小民部門:

public class CompanyMin {  private List<Employee> list = new ArrayList<>();  public CompanyMin(){    list.add(new Employee("小民", 26, "男", "程序猿"));    list.add(new Employee("小蕓", 22, "女", "測試"));    list.add(new Employee("小方", 18, "女", "測試"));    list.add(new Employee("可兒", 21, "女", "設計"));    list.add(new Employee("朗情", 19, "女", "設計")); //吐槽一下,為什么就小民一個男的,小輝部門全男的。  }  public List<Employee> getEmployees(){    return list;  }}

小輝部門:

public class CompanyHui {private Employee[] array = new Employee[3];  public CompanyHui(){    array[0] = new Employee("輝哥", 28, "男", "程序猿");    array[1] = new Employee("小紅", 23, "男", "程序猿");    array[2] = new Employee("小輝", 25, "男", "程序猿");  }  public Employee[] getEmployees(){    return array;  }}

可見小民和小輝的內(nèi)部實現(xiàn)是兩種方式,小民的人員信息容器的內(nèi)部實質是使用的一個List類存儲人員信息,而小輝的實質上使用的是一個數(shù)組,如果老板要查看人員信息就必須遍歷兩個容器:

Boss查看:

public class Boss {  public static void main(String[] args) {    CompanyHui hui = new CompanyHui();    Employee[] huiList = hui.getEmployees();    for(int i = 0; i < huiList.length; i++){      System.out.println(huiList[i]);    }    CompanyMin min = new CompanyMin();    List minList = min.getEmployees();    for(int i = 0; i < minList.size(); i++){      System.out.println(minList.get(i).toString());    }  }}

結果:

Employee{name='輝哥', age=28, sex=男, position='程序猿'}Employee{name='小紅', age=23, sex=男, position='程序猿'}Employee{name='小輝', age=25, sex=男, position='程序猿'}Employee{name='小民', age=26, sex=男, position='程序猿'}Employee{name='小蕓', age=22, sex=女, position='測試'}Employee{name='小方', age=18, sex=女, position='測試'}Employee{name='可兒', age=21, sex=女, position='設計'}Employee{name='朗情', age=19, sex=女, position='設計'}

這樣看似也沒有問題,但是如果有多個部門,每個部門有各自的實現(xiàn),那么我們就要在Boss類中增加一遍遍歷邏輯,這樣Boss類的功能會越來越多,同時暴露了內(nèi)部細節(jié)。那么我們需要定義一個迭代器接口:

public interface Iterator {  /**   * 是否還有下一個元素   *   * @return true表示有,false表示沒有   */  boolean hasNext();  /**   * 返回當前元素,并將位置移至下一位   */  Object next();}

小民的迭代器:

public class MinIterator implements Iterator{  private List<Employee> list;  private int position;  public MinIterator(List<Employee> list){    this.list = list;  }  @Override  public boolean hasNext() {    return !(position > list.size() - 1 || list.get(position) == null);  }  @Override  public Object next() {    Employee e = list.get(position);    position++;    return e;  }}

小輝的迭代器:

public class HuiIterator implements Iterator{  private Employee[] array;  private int position;  public HuiIterator(Employee[] array){    this.array = array;  }  @Override  public boolean hasNext() {    return !(position > array.length - 1 || array[position] == null);  }  @Override  public Object next() {    Employee e = array[position];    position++;    return e;  }}

定義容器類的接口:

public interface Company {  /**   * 返回一個迭代器對象   *   * @return 迭代器對象   */  Iterator iterator();}

修改一下之前的兩個容器類:

public class CompanyHui implements Company{  private Employee[] array = new Employee[3];  public CompanyHui(){    array[0] = new Employee("輝哥", 28, "男", "程序猿");    array[1] = new Employee("小紅", 23, "男", "程序猿");    array[2] = new Employee("小輝", 25, "男", "程序猿");  }  public Employee[] getEmployees(){    return array;  }  @Override  public Iterator iterator() {    return new HuiIterator(array);  }}
public class CompanyMin implements Company{  private List<Employee> list = new ArrayList<>();  public CompanyMin(){    list.add(new Employee("小民", 26, "男", "程序猿"));    list.add(new Employee("小蕓", 22, "女", "測試"));    list.add(new Employee("小方", 18, "女", "測試"));    list.add(new Employee("可兒", 21, "女", "設計"));    list.add(new Employee("朗情", 19, "女", "設計"));  }  public List<Employee> getEmployees(){    return list;  }  @Override  public Iterator iterator() {    return new MinIterator(list);  }}

Boss查看:

public class Boss {  public static void main(String[] args) {    CompanyHui hui = new CompanyHui();    check(hui.iterator());    CompanyMin min = new CompanyMin();    check(min.iterator());  }  private static void check(Iterator iterator){    while (iterator.hasNext()) {      System.out.println(iterator.next().toString());    }  }}

六、Android源碼中的迭代器模式

1、Cursor

當我們使用SQLiteDatabase的query方法查詢數(shù)據(jù)庫時,會返回一個Cursor游標對象,該游標的實質就是一個具體的迭代器,我們可以使用它來遍歷數(shù)據(jù)庫查詢所得的結果集。

七、總結

迭代器模式發(fā)展至今,幾乎所有的高級語言都有相應的內(nèi)置實現(xiàn),對于開發(fā)者而言,已經(jīng)極少會自己去實現(xiàn)迭代器了,所以本章內(nèi)容更多的是了解而非應用。

優(yōu)點:

符合面向對象設計原則中的單一職責原則。

支持對容器對象的多種遍歷。弱化了容器類與遍歷算法之間的關系。

缺點:

類文件的增加。

會出現(xiàn)ConcurrentModificationException異常。

遍歷過程是一個單向且不可逆的遍歷。

希望本文所述對大家Android程序設計有所幫助。


注:相關教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 德阳市| 边坝县| 泾川县| 武安市| 象山县| 隆回县| 咸宁市| 平泉县| 梅河口市| 鸡西市| 诸暨市| 宣城市| 白银市| 西和县| 梅州市| 兴城市| 宣武区| 米易县| 出国| 和平区| 永安市| 余庆县| 威宁| 怀远县| 项城市| 浙江省| 泽州县| 香港 | 墨江| 安阳市| 昌江| 卓尼县| 盐源县| 仁化县| 蛟河市| 冕宁县| 汨罗市| 咸丰县| 保康县| 保山市| 定安县|