容器類是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,並且新tail的next自動指向null。
tail = n;
//同時增大list的size,並且size只在這裏變化。
size ++;
}
publicint size() {
//返回的就是當前list的size
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當中。