Iterator和Iterable的区别以及使用

 

1、什么是迭代器

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

 

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

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

Iterator和Iterable的区别以及使用的更多相关文章

  1. iterator与iterable的区别和联系

    iterator与iterable   用Iterator模式实现遍历集合Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内 ...

  2. iterator和iterable的区别

    相关博客:  http://blog.csdn.net/lipengcn/article/details/51700153         Java中Iterable和Iterator的辨析 http ...

  3. 【转】Python 中 Iterator和Iterable的区别

    Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...

  4. Python 中 Iterator和Iterable的区别

    Python中 list,truple,str,dict这些都可以被迭代,但他们并不是迭代器.为什么? 因为和迭代器相比有一个很大的不同,list/truple/map/dict这些数据的大小是确定的 ...

  5. Iterator 和 Iterable 区别和联系

    首先预览下Java源码中的Iterator和Iterable: Iterable接口: public interface Iterable<T> {//这里只摘录接口中的抽象方法 /** ...

  6. for,foreach,iterator的用法和区别

    for,foreach,iterator的用法和区别 相同点:   三个都可以用来遍历数组和集合不同点:1.形式差别 for的形式是for(int i=0;i<arr.size();i++){. ...

  7. 14、Iterator跟ListIterator的区别

    14.Iterator与ListIterator的区别 在使用List,Set的时候,为了实现对其数据的遍历,会经常使用到Iterator(跌代器).使用跌代器,不需要干涉其遍历的过程,只需要每次取出 ...

  8. 【转】Java迭代:Iterator和Iterable接口

    Java迭代 : Iterator和Iterable接口 从英文意思去理解 Iterable :故名思议,实现了这个接口的集合对象支持迭代,是可迭代的.able结尾的表示 能...样,可以做.... ...

  9. Iterator 与ListIterator的区别

    Iterator 与ListIterator的区别: 1.Iterator能够迭代Set和List集合的元素,而ListIterator只能迭代List集合的元素 2.Iterator只能前向迭代,L ...

随机推荐

  1. andorid CmakeLists

    # cmake要求低版本 cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either ...

  2. shell基础:用户自定义变量

  3. Struts2第三天

    ## Struts2第三天 ## ---------- **课程回顾:Struts2框架的第二天** 1. Servlet的API * ActionContext对象 * ServletActionC ...

  4. C#会对于未赋值的变量/成员变量,给予一个初始值吗?

    如果我有程序如下: C# code   ? 1 2 3 4 5 6 7     public class My     {         public bool b;         public  ...

  5. C# 基于Aspose.Cells的数据导出到Excel

    using Aspose.Cells;  void WriteToExcel(string filePath, List<object[]> datas, string sheetName ...

  6. Django中的View视图讲解

    Django中的View视图(view.py)是负责处理用户请求和返回响应的逻辑. 视图函数或视图简而言之就是一个python函数,它接受一个web请求并返回一个Web响应. 此响应可以是网页的HTM ...

  7. Python记录2:数据类型

    一Python的数据类型可以分为可变与不可变两种: 可变类型:值改变,但是id不变,证明就是在改变原值,就是可变类型 如list   dict 列表和字典都是可变类型 不可变类型:值改变,id也跟着改 ...

  8. mysql优化(四)

    一.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where / group by / order by 涉及的列上建立索引. 1.索引失效情况. SQL什么条件会使用索引? 当字段上建有索引时, ...

  9. OC 反射-->动态创建类

    系统方法 NSLog(@"%s", __func__); //打印出类的方法名称,如: //打印结果:2018-02-22 10:52:15.394575+0800 DemoRun ...

  10. 性能测试工具Locust,一个开源性能测试工具

    性能测试工具Locust,一个开源性能测试工具使用Python代码来定义用户行为.用它可以模拟百万计的并发用户访问你的系统.1.它与目前主流的LoadRunner和Jmeter玩法都不一样.2.它完全 ...