首先附上這兩個接口JDK中的定義:
package java.lang;
import java.lang
public interface Iterable<T> {
Iterator<T> iterator();
}
package java.util;
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
} 首先你會看到這兩個接口在不同的包中,Iterable接口在lang包,Iterator在util包中,Iterable接口中實現
Iterable是1.5引入的新特性,Iterator是1.2就有了,二者都是爲了迭代造作,Iterable只是包裝了Iterator,從而允許實現此接口的對象成爲foreach語句的目標,而且這樣的話,更方便以後的擴展。JDK中的集合類,比如List一族或者Set一族,
都是實現了Iterable接口,但並不直接實現Iterator接口。
仔細想一下這麼做是有道理的。因爲Iterator接口的核心方法next()或者hasNext()
是依賴於迭代器的當前迭代位置的。
如果Collection直接實現Iterator接口,勢必導致集合對象中包含當前迭代位置的數據(指針)。
當集合在不同方法間被傳遞時,由於當前迭代位置不可預置,那麼next()方法的結果會變成不可預知。
除非再爲Iterator接口添加一個reset()方法,用來重置當前迭代位置。
但即時這樣,Collection也只能同時存在一個當前迭代位置。
而Iterable則不然,每次調用都會返回一個從頭開始計數的迭代器。
多個迭代器是互不干擾的。 下面舉例說明兩個接口的用
package yizhangsanjie; import java.util.Iterator;//必須添加引用 public class FixedCapacityStackOfStrings<Item> implements Iterable<Item> { private Item []arr; private int N;//棧的容量 //初始化構造函數 public FixedCapacityStackOfStrings(int cap) { arr=(Item[])new Object[cap]; } //擴大棧的容量 public void resize(int max) { //將大小爲N的數組擴大到一個新的大小爲max的數組中 Item[] temp=(Item[])new Object[max]; for(int i=0;i<N;i++) { temp[i]=arr[i]; } arr=temp;//重新修改數組 } //判斷棧是否爲空 public boolean isEmpty() { return N==0; } //棧的容量大小 public int size() { return N; } //進棧操作 public void push(Item item) { if(N==arr.length)//判斷棧是否滿了 resize(2*arr.length); arr[N++]=item; } //出棧操作 public Item pop() { Item item=arr[--N]; arr[N]=null;//避免對象遊離 if(N>0&&N==arr.length/4)//如果數組太大就減半 resize(arr.length/2); return item; } public Iterator<Item> iterator() { return new ReverseArrayIterator(); } private class ReverseArrayIterator implements Iterator<Item> { private int i=N; public boolean hasNext() { return i>0; } public Item next() { return arr[--i]; } public void remove() { } } }
本程序實現了棧的,非鏈表操作,分別使用了泛型技術,迭代技術,主體類繼承了Iterable接口
然後在內部類實現了Iterator接口的操作