設計模式之2 iterator模式-主要是容器類的應用

 

容器類是java當中非常重要的類。可以說,基本上每個項目都要用到容器類。通過這個設計模式,主要是反映通過接口來控制提供規定的方法名。具體的實現交給不同的具體的類去實現。collection接口是如此,iterator也是如此。

 

本文word版本(可下載):

 

http://wenku.baidu.com/view/1dc00c6acaaedd3383c4d34a.html

 

首先模擬實現arraylist

package com.bjsxt.dp.iterator;

 

import com.bjsxt.dp.iterator.*;

 

publicclass ArrayListimplements Collection {

    //初始化就是10個對象

    Object[] objects = new Object[10];

    intindex = 0;

    publicvoid add(Object o) {

      

       //如果到達數組上限,就翻倍,並且把原數組裏面的所有內容複製到新數組當中

       if(index ==objects.length) {

           Object[] newObjects =new Object[objects.length * 2];

           System.arraycopy(objects, 0, newObjects, 0,objects.length);

          

           //最關鍵的一步在這裏,把老數組的引用指向新數組,那麼從arraylist的使用者的角度來說,是看不到內部數組翻倍了。

          

           objects = newObjects;

       }

       objects[index] = o;

       index ++;

    }

   

    publicint size() {

       //返回的是數組當前的index,而不是數組的真實大小

       returnindex;

    }

   

    //向外提供的iterator

    public Iterator iterator() {

      

       returnnew ArrayListIterator();

    }

   

    //通過一個內部類來實現iterator接口。

    privateclass ArrayListIteratorimplements Iterator {

       privateintcurrentIndex = 0;

 

       //目前index的值大於數組的size,就沒有下一個了。

       publicboolean hasNext() {

           if(currentIndex >=index)returnfalse;

           elsereturntrue;

       }

 

       //返回當前數組對應的index處的對象,並把遊標指向下一個位置

       public Object next() {

           Object o = objects[currentIndex];

           currentIndex ++;

           return o;

       }

      

    }

}

 

通過一個通用的接口,collection

package com.bjsxt.dp.iterator;

 

//通過接口,約束方法的名字

publicinterface Collection {

    void add(Object o);

    int size();

    //指定了容器類必須提供iterator方法,這個方法的返回值是Iterator

    Iterator iterator();

}

 

通過另外一個接口,iterator

package com.bjsxt.dp.iterator;

 

publicinterface Iterator {

    //兩個方法,第一是返回一個object對象,第二是看還有沒有下一個節點。

    Object next();

    boolean hasNext();

}

 

 

對於linklist,裏面放的元素是node

 

package com.bjsxt.dp.iterator;

 

publicclass Node {

    //node的構造方法,傳遞兩個參數,第一是數據本身,第二就是指向下一個節點的next

    public Node(Object data, Node next) {

       super();

       this.data = data;

       this.next = next;

    }

   

    public Object getData() {

       returndata;

    }

    publicvoid setData(Object data) {

       this.data = data;

    }

    public Node getNext() {

       returnnext;

    }

    publicvoid setNext(Node next) {

       this.next = next;

    }

    private Objectdata;

    private Nodenext;

}

 

linkedlist

package com.bjsxt.dp.iterator;

 

import com.bjsxt.dp.iterator.Collection;

 

publicclass LinkedListimplements Collection {

    //第一個節點

    Node head = null;

    //最後一個節點

    Node tail = null;

   

    //大小

    intsize = 0;

   

    //添加項目的方法

    publicvoid add(Object o) {

       //添加的第一個節點  

       Node n = new Node(o,null);

       //只有一個節點的情況,它既是頭又是尾

       if(head ==null) {

           head = n;

           tail = n;

       }     

       //每次在最後添加節點,把上一個節點的next指向新添加的節點,並把新節點的next指向null

       //當前tail(也就是現在list當中的最後一個元素)的next指向新節點

       tail.setNext(n);

       //新節點成爲新的tail,並且新tailnext自動指向null

       tail = n;

       //同時增大listsize,並且size只在這裏變化。

       size ++;

    }

   

    publicint size() {

       //返回的就是當前listsize

       returnsize;

    }

 

    //@Override

    public Iterator iterator() {

       returnnull;

    }

}

 

假設容器當中放的是cat

package com.bjsxt.dp.iterator;

 

publicclass Cat {

    public Cat(int id) {

       super();

       this.id = id;

    }

 

    privateintid;

   

    @Override

    public String toString() {

       return"cat:" +id;

    }

}

 

主類,測試用類。

 

package com.bjsxt.dp.iterator;

 

import com.bjsxt.dp.iterator.ArrayList;

import com.bjsxt.dp.iterator.LinkedList;

 

publicclass Test {

    publicstaticvoid main(String[] args) {

       //ArrayList al = newArrayList();

       //LinkedList al = newLinkedList();

      

      

       //需要靈活的替換容器的類型。

       //體會多態的引用,和靈活的設計模式,一般都是用父類的引用。然後new不同的子類對象。

       //多態,利用父類引用指向子類對象。這裏叫做面向接口的編程。

       Collection c = new ArrayList();

       for(int i=0; i<15; i++) {

           c.add(new Cat(i));

       }

       System.out.println(c.size());

      

       //容器的遍歷:找到一個統一的遍歷方式,事實上,iterator也只是一個接口。

       //接口當中的遍歷方法在每個具體的容器類當中實現。

       //需要c提供一個iterator,每個具體的容器類提供不同的iterator。比如arraylist就是ArrayListIterator

      

       //使用來自當前容器的iterator

       Iterator it = c.iterator();

      

       //當我能找到下一個,就把它返回。

       while(it.hasNext()) {

           //next方法返回的是一個object對象。注意這裏沒有next++方法,也就說,數組遊標沒有指向下一個。

           //是因爲具體的遊標實現在每個容器內部,而不是在iterator當中。

           Object o = it.next();

           System.out.print(o +" ");

       }

    }

}

 

 

思想核心:

1.      通過一個通用的接口,collection來限制所有容器都必須實現的方法,方法名必須一致。從而在使用的時候,可以是顯示通過父類的對象來指向子類的引用。也就是的多態來訪問容器。

2.      每個具體的容器在實現collection當中的方法,自己添加了具體的實現。每個容器實現的方法不一樣,但是對容器的使用者test.java來說,看不到內部實現的細節,使用起來都是一樣。體現了面向對象的封裝,隱藏思想。

3.      爲了提供一個統一的遍歷,在collection當時提供了iterator方法。那麼所有的容器都要去提供iterator.iterator本身是一個接口,這個接口的作用就是用來遍歷容器當中的對象。在容器內部,採取了內部類的方式來實現這個接口。對於容器當中每個元素的遍歷,每個容器實現的方法都不一樣,但是對容器的使用者test.java來說,看不到內部實現的細節,使用起來都是一樣。再一次體現了面向對象的封裝,隱藏思想。

4.      注意一下iterator當中的兩個方法,一個是hasNext(),這個方法的返回值是boolean,也就是說看看容器當中還有沒有下一個對象。更重要的是next()方法,它的返回值是一個object對象。注意這裏沒有next++方法,也就說,數組遊標沒有指向下一個。是因爲具體的遊標實現在每個容器內部,而不是在iterator當中。

 

發佈了65 篇原創文章 · 獲贊 19 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章