zoukankan      html  css  js  c++  java
  • Stream和迭代器的区别

    迭代器的定义

    迭代器是提供一种访问一个集合内各个元素的同时并不需要暴露内部细节的一种途径,java为我们提供了Iterator和Iterable两种接口实现对集合的迭代,迭代器的主要用法就是以hasNext()为条件,在通过next()方法获取集合内的每一个元素,直至hasNext()为false结束迭代;

    补充:iterator和iterable的区别

    1、首先二者都是接口Iterator是java.util包下得接口,而Iterable是java.lang下的接口;

    2、Iterator是迭代器类,而Iterable中则封装Iterator接口(foreach方法就包含在其中);

    3、目前常用的集合如Conllection、List、Set都是Iterable的实现类;

    4、Iterator中和核心的方法next()、hasnext()、remove()都相当依赖指针的当前位置,如果多个集合都实现Iterator接口则会存在指针无法确定当前位置从而无法正常迭代。而Iterable接口则在Iterator的基础上增加一个reset()方法,从而确保每次迭代都是从第一个元素开始;

    Stream的定义

    首先Stream是java1.8才推出的一项功能,与我们熟知的java.io包下的InputStream和OutputStream是完全不同的概念。Stream 是对原有迭代器的功能增强,它专注于对集合对象进行各种非常便利、高效的聚合操作,或者大批量数据操作 。借助同样是1.8新出现的Lambda表达式极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用Fork/Join框架并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错, 但使用Stream API无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。

    Stream即不是集合元素,也不是数据结构并不保存数据,是有一个依赖算法和计算的高级版的 Iterator。原始版本的Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作,而高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

    Stream就如同一个迭代器,单向不可往复数据只能遍历一次,遍历完成后就无法再次使用。

    二者区别

    Stream最大的两个特点就是并行化操作和数据源可以无限大;

    不过在在介绍上述区别前,我们需要了解一个概念什么是聚合操作?

    在传统的java业务处理的时候,我们常常需要查询例如“A客户每月平均消费金额”、“线上商城中某个专区中最贵的在售商品”等等,这写具备复数条件的嵌套查询操作就可以视为聚合操作,处理这些问题我们不得不依赖关系型数据库来完成操作;

    但是在现今这个数据大爆炸的时代多样化且海量的数据,关系型数据性能的捉襟见肘让我们不得不抛弃,从而转为以底层返回数据为基础在上层对数据进行二次处理,而Java API在这块极少量的辅助方法导致我们不得不使用迭代完成相关的聚合操作,这样的处理方式不仅效率低下且大量的二次数据处理代码也增加bug的概率; 

    Stream的出现就是为了解决上述的问题,首先Stream的处理逻辑是数据源(source) → 数据转换 → 执行操作获取想要的结果,期间可以穿插多次数据转换由多个操作组成一个链条,也就是所谓的流管道

    流的操作类型分为两种:

    Intermediate:一个流可以后面跟随零个或多个intermediate操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。但是这些类操作都是惰性化的(lazy),仅仅调用到这类方法,并没有真正开始流的遍历。

    Terminal:一个流只能有一个terminal操作,当这个操作执行后,流就被结束了,无法再被操作。所以这必定是流的最后一个操作。Terminal操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个side effect(附加结果)。

    补充:需要注意的是Stream流中进行了N次intermediate操作,这并不意味着Stream在执行时需要进行N次for循环完成操作。因为intermediate是惰性操作,所以只会在执行terminal时,所有intermediate操作会融合起来,一次循环就能完成。也可以简单理解为Stream理由有个操作集合,每次转换操作都被存入这个集合,只有执行terminal操作时循环遍历之前的操作集合并执行。

    还有一种操作被称为short-circuiting(短路)用于操作无线大的数据源时的一个必要的操作条件,可以理解为limit类似的

     简单说,对Stream的使用就是实现一个filter-map-reduce过程,产生一个最终结果,或者产生一个附加结果(side effect)。

  • 相关阅读:
    Distinct Substrings(spoj 694)
    Musical Theme
    Milk Patterns(poj 3261)
    Repeated Substrings(UVAlive 6869)
    喵星球上的点名(bzoj 2754)
    滑雪与时间胶囊(bzoj 2753)
    莫比乌斯函数之和(51nod 1244)
    欧拉函数之和(51nod 1239)
    数表(bzoj 3529)
    欧拉函数模板
  • 原文地址:https://www.cnblogs.com/hasagi/p/11140609.html
Copyright © 2011-2022 走看看