Iterator和Iterable的区别以及使用

Iterator和Iterable的区别以及使用

 

1、什么是迭代器

迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来

 

Iterable,该接口包含一个能够产生Iterator接口的iterator()方法,并且Iterable对象被foreach用来在序列中移动,因此创建的任何实现了Iterable接口的类都可以将它用于foreach。

Iterator和Iterable的区别以及使用

1、        Iterable接口:从继承结构中可以看出,Iterable接口是Collection的顶层接口,所以Iterable是数据结构,用来存放数据的地方。

这个接口只是为了让对象实现for-each loop声明而存在的。

iterable接口最重要的方法是:Iterator<T> iterator()//生成迭代器。否则无法实现for-each

default Spliterator<T>  spliterator()//在这 Iterable创建描述元素的 Spliterator//Interface Spliterator<T>用于遍历和划分源的元素的对象。所涵盖的spliterator元素的来源可能是,例如,一个数组,一个 Collection,IO通道,或一个函数发生器。

default void    forEach(Consumer<? super T> action)

2、        Iterator接口:是定义了迭代逻辑的接口,即:用于遍历Collection(集合类)中数据的标准访问方法。

Iterator的出现是为了替代Enumeration.

它和Enumeration不同的是,它可以删除迭代的内容。并且被更好的命名

这个接口只有四个方法:

boolean hasNext()

E next()

default void remove()

default void forEachRemaining(Consumer<? super E> action)

Iterator接口是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。

如果没有使用Iterator,遍历一个数组的方法是使用索引:
for(int i=0; i<array.size(); i++) { ... get(i) ... }
而访问一个链表(LinkedList)又必须使用while循环
while((e=e.next())!=null) { ... e.data() ... }
以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。
更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。

而Iterator模式总是用同一种逻辑来遍历集合

客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前""向后""取当前元素"的命令,就可以间接遍历整个集合

Iterator源码:

public interface Iterator<E> {

boolean hasNext();

E next();

default void remove() {

throw new UnsupportedOperationException("remove");

}

default void
forEachRemaining(Consumer<? super E> action) {

Objects.requireNonNull(action);

while (hasNext())

action.accept(next());

}

}

JDK1.5中,还对上面的代码在语法上作了简化(但是限于只读,如果需要remove,还是直接使用iterator)

每一种集合类返回的Iterator具体类型可能不同,Array可能返回ArrayIteratorSet可能返回SetIteratorTree可能返回TreeIterator,但是它们都实现了Iterator接口,因此,客户端不关心到底是哪种Iterator,它只需要获得这个Iterator接口即可,这就是面向对象的威力。

 

3、      
为什么一定要去实现Iterable这个接口呢?为什么不直接实现Iterator接口呢?

看一下JDK中的集合类,比如List一族或者Set一族,
都是实现了Iterable接口,但并不直接实现Iterator接口。
仔细想一下这么做是有道理的。因为Iterator接口的核心方法next()或者hasNext()
依赖于迭代器的当前迭代位置的。
如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)
当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。
除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。
但即时这样,Collection也只能同时存在一个当前迭代位置。
Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。
多个迭代器是互不干扰的。

 

借鉴大佬:

http://www.cnblogs.com/highriver/archive/2011/07/27/2077913.html

上一篇:转-Spring 注解学习手札(七) 补遗——@ResponseBody,@RequestBody,@PathVariable


下一篇:CentOS 6.3下Samba服务器的安装与配置详解