java中Iterator和Iterable的区别
(1)Iterable接口 (java.lang.Iterable) 是Java集合的*接口之一,Iterable接口中只包含一个方法,就是一个iterator()方法,用来返回一个Iterator类型的对象,或者说返回一个实现了Iterator接口的对象。
public interface Iterable<T> {
Iterator<T> iterator();
}
(2)public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
}
(3)Iterator和Iterable都是接口。
集合类:list、set、collection实现了Iterable接口,这样对象就可以调用iterator()方法。
Interator模式:方便表里list和set,不需要知道collection中的是list和set,直接调用iterator()方法就行,屏蔽了细节。比如 HashMap类就实现了Iterable接口,而要访问或打印出Map中所有内容时,就可以这样:
- HashMap hashMap;
- Iterator iter = hashMap.iterator();
- while(iter.hashNext()) {
- String s = iter.next();
- }
(4)那么Iterator和Iterable有什么区别呢,Iterable中有个iterator()方法可以产生Iterator类型的接口,为什么要这么做,而不是让集合类直接实现iterator接口呢?
因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。 如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。 当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。 除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。但即时这样,Collection也只能同时存在一个当前迭代位置,而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器,多个迭代器是互不干扰的。
(5)
我在刚开始看的时候,第一个疑问就是:为什么Collection接口要继承于Iterable接口,而不是Iterator接口?在*上找了很多回答,总结了三点,希望对刚刚接触Collection集合类也在这里有困惑的同学有所帮助。原因大致有三点:
1. 在jdk 1.5以后,引入了Iterable,使用foreach语句(增强型for循环)必须使用Iterable类。
2. Java设计者让Collection继承于Iterable而不是Iterator接口。首先要明确的是,Iterable的子类Collection,Collection的子类List,Set等,这些是数据结构或者说放数据的地方。Iterator是定义了迭代逻辑的对象,让迭代逻辑和数据结构分离开来,这样的好处是可以在一种数据结构上实现多种迭代逻辑。
3. 更重要的一点是:每一次调用Iterable的Iterator()方法,都会返回一个从头开始的Iterator对象,各个Iterator对象之间不会相互干扰,这样保证了可以同时对一个数据结构进行多个遍历。这是因为每个循环都是用了独立的迭代器Iterator对象。