【java設計模式】(6)---迭代器模式(案例解析)

設計模式之迭代器模式

 

1、java迭代器介紹

一、迭代器接口

在jdk中,與迭代器相關的接口有兩個:Iterator 與 Iterable。html

Iterator:迭代器,Iterator及其子類一般是迭代器自己的結構與方法;迭代器是一種模式,它可使得對於序列類型的數據結構的遍歷行爲與被遍歷的對象分離,即咱們無需關心該序列的底層結構是什麼樣子的。只要拿到java

這個對象,使用迭代器就能夠遍歷這個對象的內部。設計模式

Iterable:可迭代的,那些想用到迭代器功能的其它類,如AbstractList HashMap等,須要實現該接口。 數據結構

1)Iteratorapp

      Java提供一個專門的迭代器<<interface>>Iterator,咱們能夠對某個序列實現該interface,來提供標準的Java迭代器。Iterator接口實現後的功能是「使用」一個迭代器。ide

Package java.util; public interface Iterator<E> { //判斷是否存在下一個對象元素 
    boolean hasNext(); //得到下一個元素
 E next(); //移除下一個元素
    void remove(); } 

 2)Iterable函數

       Java中還提供了一個Iterable接口,Iterable接口實現後的功能是「返回」一個迭代器(Iterator),咱們經常使用的實現了該接口的子接口有: Collection<E>, Deque<E>, List<E>, Queue<E>, Set<E> 等.該接口的iterator()方測試

法返回一個標準的Iterator實現。this

public interface Iterable<T> { Iterator<T> iterator(); } 

 二、迭代器的實現

看完源碼,咱們來看看迭代器是如何使用的: spa

    1) 若類A想要使用迭代器,則它的類聲明部分爲 class A implement Iterable 

    2) 在類A實現中,要實現Iterable接口中的惟一方法:Iterator<T> iterator(); 這個方法用於返回一個迭代器,即Iterator接口及其子類; 

    3) 在類A中,定義一個內部類S,專門用於實現Iterator接口,定製類A自已的迭代器實現。

以下:

//A實現Iterable接口
class A implement Iterable { //該接口返回一個Iterator對象
    Iterator<T> iterator() {...} class S implement Iterator<E> { //上面這個對象會有具體實現的方法
        boolean hasNext() {....} E next() {....} void remove() {....} } }

下面咱們來看下抽象類AbstractList的jdk源碼

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口實現了Collection<E>, Iterable<E> 
   
   protected AbstractList() { } ... // 這裏返回一個迭代器對象 
   public Iterator<E> iterator() { return new Itr(); } // Itr內部類實現迭代器 
    private class Itr implements Iterator<E> { int cursor = 0; int lastRet = -1; int expectedModCount = modCount; // 實現hasNext方法 
    public boolean hasNext() { return cursor != size(); } // 實現next方法 
    public E next() { //判斷是否有下一個
 checkForComodification(); try { E next = get(cursor); lastRet = cursor++; //返回下一個 
        return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } } // 實現remove方法 
    public void remove() { if (lastRet == -1) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } //判斷是否有下一個方法
    final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } } 

三、小案例

//實現Iterable
class ScanAppleStore implements Iterable<String> { ArrayList<String> appleStore = new ArrayList<String>(); //爲初始appleStore賦值
 ScanAppleStore() { Collections.addAll(appleStore, "Sweet", "Sour", "Bitter", "litter Sweet", "litter Sour", "litter Bitter"); System.out.print(appleStore); } //重寫Iterator方法
 @Override public Iterator<String> iterator() { return new Iterator<String>() { private int i = 0; public boolean hasNext() { if (i < appleStore.size()) { return true; } else { return false; } } public String next() { return appleStore.get(i++); } public void remove() { System.out.print("not defined!"); } }; } public Iterable<String> reverseIterator() { return new Iterable<String>() { public Iterator<String> iterator() { return new Iterator<String>() { private int i = appleStore.size() - 1; public boolean hasNext() { if (i > -1) { return true; } else { return false; } } public String next() { return appleStore.get(i--); } public void remove() { System.out.print("not defined!"); } }; } }; }}

測試類

public class TestIterable { //構造函數初始化
 TestIterable() { ScanAppleStore appleTree = new ScanAppleStore(); //採用系統自帶的迭代器
        System.out.println("採用系統自帶的迭代器iterator:"); for (String str : appleTree) { System.out.println(str); } System.out.println("======================"); System.out.println("採用本身從新迭代器,讓相反輸出"); //採用本身從新迭代器,讓相反輸出
        for (String str : appleTree.reverseIterator()) { System.out.println(str); } } public  static void main(String[] args) { TestIterable a = new TestIterable(); } }

運行結果

[Sweet, Sour, Bitter, litter Sweet, litter Sour, litter Bitter]
採用系統自帶迭代器iterator: Sweet Sour Bitter litter Sweet litter Sour litter Bitter
====================== 採用本身從新迭代器,讓相反輸出: litter Bitter litter Sour litter Sweet Bitter Sour Sweet

 

2、迭代器模式

一、什麼是迭代器模式

   GOF給出的定義爲:提供一種方法訪問一個容器(container)對象中各個元素,而又不需暴露該對象的內部細節。  

   Iterator模式就是分離了集合對象的遍歷行爲,抽象出一個迭代器類來負責,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明的訪問集合內部的數據。

二、迭代器模式角色組成

       1) 迭代器角色(Iterator):迭代器角色負責定義訪問和遍歷元素的接口。 

  2) 具體迭代器角色(Concrete Iterator):具體迭代器角色要實現迭代器接口,並要記錄遍歷中的當前位置。 

       3) 容器角色(Container):容器角色負責提供建立具體迭代器角色的接口。 

    4) 具體容器角色(Concrete Container):具體容器角色實現建立具體迭代器角色的接口——這個具體迭代器角色於該容器的結構相關。 

三、案例解析

  1)迭代器角色

public interface Iterator { public Object next(); public boolean hasNext(); }

 2)具體迭代器角色

public class ConcreteIterator implements Iterator { private List list = new ArrayList(); private int cursor = 0; public ConcreteIterator(List list) { this.list = list; } @Override public Object next() { Object obj = null; if (this.hasNext()) { obj = this.list.get(cursor++); } return obj; } @Override public boolean hasNext() { if (cursor == list.size()) { return false; } return true; } }

3)容器角色

public interface Aggregate { public void add(Object obj); public void remove(Object obj); public Iterator iterator(); }

4) 具體容器角色

public class ConcreteAggregate implements Aggregate { private List list = new ArrayList(); @Override public void add(Object obj) { list.add(obj); } @Override public void remove(Object obj) { list.remove(obj); } @Override public Iterator iterator() { return new ConcreteIterator(list); } }

測試類

public class Client { public static void main(String[] args) { Aggregate ag = new ConcreteAggregate(); ag.add("小明"); ag.add("小紅"); ag.add("小剛"); Iterator it = ag.iterator(); while (it.hasNext()) { String str = (String) it.next(); System.out.println(str); } }}

運行結果

小明 小紅 小剛

四、迭代器優勢和缺點

優勢

    1)它支持以不一樣的方式遍歷一個聚合對象。
    2)迭代器簡化了聚合類。
    3)在同一個聚合上能夠有多個遍歷。 
    4)在迭代器模式中,增長新的聚合類和迭代器類都很方便,無須修改原有代碼。 

缺點

    因爲迭代器模式將存儲數據遍歷數據職責分離,增長新的聚合類須要對應增長新的迭代器類,類的個數成對增長,這在必定程度上增長了系統的複雜性。

 

參考

其實這整篇文章幾乎都來自該篇文章,用參考都不太好意思,哈哈。

     JAVA迭代器與迭代模式

 

想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。中校【7】 

相關文章
相關標籤/搜索