首先附上这两个接口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接口的操作
浅谈Iterator iterable