Stream实现了对数据源的流式处理,它可以并行操作,提高数据处理效率。

什么是流

流不是集合,它不对数据做保存,只是最数据进行算法处理,比如最大值,最小值,排序等操作。Stream会在数据源内部隐式的遍历进行处理。Stream会并行遍历数据,将数据分成若干段,同时进行处理,最终汇总结果一起输出。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。

特点

首先对stream的操作可以分为两类,中间操作(intermediate operations)和结束操作(terminal operations):

  • 中间操作总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream。
  • 结束操作会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。
  • 无存储。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
  • 为函数式编程而生。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。
  • 惰式执行。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
  • 可消费性。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

使用方法

1.构造流的方法

public class StreamStudy {public static void main(String[] args) throws Exception {//1. ofStream<String> stream  = Stream.of("hello","java","python");// 2. ArraysString [] strArray = new String[] {"hello","java","python"};stream = Stream.of(strArray);stream = Arrays.stream(strArray);// 3. CollectionsList<String> list = Arrays.asList(strArray);stream = list.stream();System.out.println(stream.findAny());}}

最终只返回第一个结果: Optional[hello]

2. 流转换为其它数据结构

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python"};List<String> list = Arrays.asList(strArray);// to arraySystem.out.println(list.stream().toArray()[0]);// to listSystem.out.println(list.stream().collect(Collectors.toList()));// to stringSystem.out.println(list.stream().collect(Collectors.joining()).toString());}}

输出:
hello
[hello, java, python]
hellojavapython

3. 流的操作

  • Intermediate (map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered)
  • Terminal(forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator)
  • Short-circuiting(anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit)

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

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

4.基础的使用

1.map+forEach

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python"};List<String> list = Arrays.asList(strArray);list.stream().map((v) ->v.toUpperCase()).forEach(t -> System.out.println(t));}}

将list中的所有字母转换成大写,然后遍历输出。 实际list中的值并没有改变,我们只是借助Stream来做业务处理。
输出 :
HELLO
JAVA
PYTHON

2.filter+map+forEach

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python"};List<String> list = Arrays.asList(strArray);list.stream().filter(f -> f.length()>4).map(v ->v.toUpperCase()).forEach(t -> System.out.println(t));}}

先filter过滤,然后map字母大写,最后forEach输出结果:
HELLO
PYTHON

3. filter+sorted+map+forEach

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python","node","react","vue"};List<String> list = Arrays.asList(strArray);list.stream().filter(f -> f.length()>3).sorted((a,b) -> b.compareTo(a)).map(v ->v.toUpperCase()).forEach(t -> System.out.println(t));}}

先filter过滤,然后sorted排序,然后map字母大写,最后forEach输出结果:
REACT
PYTHON
NODE
JAVA
HELLO

4. filter+sorted+map+distinct+forEach

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python","node","react","vue","React"};List<String> list = Arrays.asList(strArray);list.stream().filter(f -> f.length()>3).sorted((a,b) -> b.compareTo(a)).map(v ->v.toUpperCase()).distinct().forEach(t -> System.out.println(t));}}

distinct去重,使用 Object.equals(Object)来判断是否重复,最终只留下一个REACT,结果:
REACT
PYTHON
NODE
JAVA
HELLO

5. filter+sorted+map+distinct+limit+forEach

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python","node","react","vue","React"};List<String> list = Arrays.asList(strArray);list.stream().filter(f -> f.length()>3).sorted((a,b) -> b.compareTo(a)).map(v ->v.toUpperCase()).distinct().limit(3).forEach(t -> System.out.println(t));}}

limit限制元素个数,这里着要前3个结果:
REACT
PYTHON
NODE

6.filter+sorted+map+distinct+limit+peek+forEach

public class StreamStudy {public static void main(String[] args) throws Exception {String [] strArray = new String[] {"hello","java","python","node","react","vue","React"};List<String> list = Arrays.asList(strArray);list.stream().filter(f -> f.length()>3).sorted((a,b) -> b.compareTo(a)).map(v ->v.toUpperCase()).distinct().limit(3).peek(p -> p.toLowerCase()).forEach(t -> System.out.println(t));}}

peek会对每个元素执行操作,并返回包含原stream元素的新Stream,什么意思呢?先看结果:
REACT
PYTHON
NODE
并不是我们看到的小写,因为peek产生的新的stream并不是我们已开始处理的Stream,所以我们看到的还是大写。如果你的处理过程中涉及一些额外逻辑,但不影响最终结果,那么你可以使用peek去搞一个新的Stream去处理。

7.总结

我们主要使用的是Intermediate 中的方法进行数据处理,Terminal 中的方法只能使用一个,这意味着对流的处理终止,这时才开始执行前面的那些Intermediate方法。最后对一些方法作一些解释,就不一一演示了:
forEach遍历、 forEachOrdered按顺序遍历、 toArray结果转换成数组、 reduce结果中的元素进行组合、 collect结果转换成集合、 min结果中最小值、 max结果中最大值、 count结果中元素数量、 anyMatch结果中存在元素满足某一条件、 allMatch结果中所有元素都满足某一条件、 noneMatch结果中所有元素都不满足某一条件、 findFirst结果中第一条数据 、 findAny结果中的任意一条数据、 iterator遍历

欢迎关注我的公众号mike啥都想搞,有更多教程资料相送。

JDK 1.8 新特性学习(Stream)相关推荐

  1. Java8新特性学习_001_(Lambda表达式,函数式接口,方法引用,Stream类,Optional类)

    目录 ■代码 ■代码运行结果 ■代码说明 ・44行:Stream的.foreach方法ー参数类型:函数式接口 ・82行:Interface中,default方法 ・92行   Stream的.max方 ...

  2. java8新特性学习笔记(Lambda,stream(),filter(),collect(),map())

    文章目录 1.lambda表达式(重点) 1.需求分析 2.Lambda表达式初体验 3.Lambda的语法规则 3.1 Lambda练习1 3.1 Lambda练习2 4.Lambda表达式的原理 ...

  3. 跟我学 Java 8 新特性之 Stream 流(二)关键知识点

    转载自   跟我学 Java 8 新特性之 Stream 流(二)关键知识点 我们的第一篇文章,主要是通过一个Demo,让大家体验了一下使用流API的那种酣畅淋漓的感觉.如果你没有实践,我还是再次呼吁 ...

  4. Java8新特性学习笔记

    Java8新特性学习笔记 文章目录 Java8新特性学习笔记 一.接口和日期处理 1.接口增强 1.1.JDK8以前 VS JDK8 1)接口定义: 1.2.默认方法(default) 1)默认方法格 ...

  5. 跟我学 Java 8 新特性之 Stream 流(六)收集

    转载自   跟我学 Java 8 新特性之 Stream 流(六)收集 我们前面的五篇文章基本都是在说将一个集合转成一个流,然后对流进行操作,其实这种操作是最多的,但有时候我们也是需要从流中收集起一些 ...

  6. 跟我学 Java 8 新特性之 Stream 流(四)并行流

    转载自   跟我学 Java 8 新特性之 Stream 流(四)并行流 随着对流API认识的慢慢深入,本章我们要讨论的知识点是流API里面的并行流了. 在开始讨论并行流之前,我先引发一下大家的思考, ...

  7. 跟我学 Java 8 新特性之 Stream 流(五)映射

    转载自   跟我学 Java 8 新特性之 Stream 流(五)映射 经过了前面四篇文章的学习,相信大家对Stream流已经是相当的熟悉了,同时也掌握了一些高级功能了,如果你之前有阅读过集合框架的基 ...

  8. JDK 5 ~ 10 新特性倾情整理

    转载自 JDK 5 ~ 10 新特性倾情整理 最近连 JDK11都在准备发布的路上了,大家都整明白了吗?也许现在大部分人还在用6-8,8的新特性都没用熟,9刚出不久,10-11就不用说了. 为了大家对 ...

  9. JAVA8的新特性之Stream

    JAVA8的新特性之Stream 1.概述: 在jdk1.8中,提供了一个Stream,可以对数据进行过滤 2.好处: 比不断自定义循环,要简单很多 Stream类型数据的获取 1.Collectio ...

  10. 各个JDK版本的新特性

    一.各个JDK版本的新特性 (1)JDK 5 : 1 . 自动装箱 2 . 泛型 3 . 动态注释 4 . 枚举 5 . 可变长参数 6 . 遍历循环 7 . 改进了 Java 的内存模型 8 . 提 ...

最新文章

  1. linux打开文件命令occ,Linux系统查看文件内容的命令有哪些?
  2. Java第四次作业——面向对象高级特性(继承和多态)
  3. 无法在流的结尾之外进行读取_IO流,字节流,字符流
  4. js map 只输出key_什么时候适合使用Map而不是Object
  5. 关于C#中使用SQLDMO来获取数据库中的一些操作
  6. 书生云王东临:真正的超融合产品要像“机器猫” 开箱即用
  7. wp insert post 插入文章到数据库
  8. 清华大学博士,就12年前抄袭一事公开道歉
  9. 【华为云技术分享】云图说 | 华为云AnyStack on BMS解决方案:助力线下虚拟化业务迁移上云
  10. 1月4日云栖精选夜读:阿里工程师如何叫外卖?99%的人猜不到
  11. python删除文件代码_python2.7删除文件夹和删除文件代码实例
  12. VScode加文件头的方式
  13. 【Java学习笔记】之家庭账目管理系统
  14. 字体加密woff(@font-face)防爬-学习记录
  15. win中q-dir,everything,Windows Tabs,Clover各种效率神器(搜索,资源管理器,多标签)
  16. 【openface : RuntimeError: Unable to open shape_predictor_68_face_landmarks.dat】
  17. Java实体类转Map、Map转实体类
  18. 禁止input密码自动填充及浏览器记住密码完整解决方案
  19. 网工知识角-思科华为的网络工程师常用工具盘点
  20. AdGuard常规设置的介绍

热门文章

  1. mysql opxe_PXE安装系统
  2. HTML判断JSON长度,javascript如何判断是否为json?
  3. 显微镜自动聚焦原理是什么_自动玻璃感应门原理是什么?看看东莞装修网怎么说...
  4. python---用python实现插入排序
  5. jdk32位安装包下载_MySQL 8.0.19安装图文详解!手把手教会您从下载到安装成功
  6. 图表位置下移_excel图表技能:如何更准确的表现营业额的变化趋势
  7. php找零页面,找零问题
  8. 梯度下降算法动图_Deep Learning|神经网络原理学习笔记(5) :随机梯度下降算法SGD(附手绘图)、离线学习与在线学习...
  9. 大数据平台搭建_【他山之石】自研搭建Hadoop数据科学开发环境,促进大数据平台建设降本增效...
  10. python网页教程_python 查询 网页Python基础教程01 Hello World!