一个Stream表面上看与一个集合很类似,允许你改变和获取数据。但是实际上他与集合是有很大区别的:

  • Stream自己不会存储元素。元素可能被存储在底层的集合中,或者根据需要产生出来。
  • Stream操作符不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  • Stream操作符可能是延迟执行的。意味着他们会等到需要结果的时候才执行。

下面是一段如何并行统计长单词的代码:

long count = words.parallelStream()
.filter(w->w.length()>12).count();

Stream遵循“做什么,而不是怎么去做”的原则。在我们的示例中,描述了需要做什么:获得长单词并对他们的个数进行统计。我们没有指定按照什么顺序,或者在哪个线程中做,他们都是理所当然发生的。相反,循环一开始就需要指定如何计算,因此就失去了优化的机会。

当你使用Stream时,你会通过三个阶段来建立一个操作流水线。

  • 创建一个Stream
  • 在一个或多个步骤中,指定将初始Stream转换为另一个Stream的中间操作。
  • 使用一个终止操作来产生一个结果。该操作会强制它之前的延迟操作立即执行。在这之后,该Stream就不会再被使用了。

在我们的示例中,通过stream或parallelStream方法创建Stream,再通过filter方法对其进行准换,而count就是终止操作。

一、创建Stream

下面展示几种创建Stream的方法:

Stream<String> stream = Stream.of("aaa", "bbb", "ccc", "ddd");
Stream<String> echos = Stream.generate(() -> "Echo");
Stream<Double> randoms = Stream.generate(Math::random);
Stream<BigInteger> integers = Stream.iterate(BigInteger.ZERO,
n -> n.add(BigInteger.ONE));

二、提取子流和组合流

Stream.limit(n)会返回一个包含n个元素的新流(如果原始流长度小于n,则会返回原始的流)。这个方法特别适用于剪裁指定长度的流。例如:

Stream<Double> randoms = Stream.generate(Math::random).limit(100);

会返回一个包含100个随机数字的流。

Stream.skip(n)刚好相反,他会丢弃掉前面的n个元素。

Stream.concat可以将两个流连接到一起。当然,第一个流的长度不应该是无限的,否则第二个流就永远没有机会被添加到第一个流的后面。

三、简单的聚合方法

  • count会返回流中元素总数
  • max和min分别返回流中最大值和最小值
  • findFirst会返回非空集合的第一个值,它通常与filter方法结合使用。
Optional<String> startWithQ = words.filter(s->s.startWith("Q")).findFirst();
  • 如果想找到所有匹配的元素,那么可以使用findAny方法。这个方法在对流进行并行执行时十分有效,因为只要在任何片段中发现了第一个匹配的元素,都会结束整个计算。
Optional<String> startsWithQ
= words.parallel().filter(s->s.startsWith("Q")).findAny();
  • 如果你只希望知道流中是否含有匹配元素,可以使用anyWatch方法。该方法可以接受一个predicate参数,因此你不需要filter方法。
boolean aWordStartsWithQ
= words.parallel().anyMatch(s->s.startsWith("Q"));
  • Java 8中还提供了两个方法allMatch和noneMatch,他们分别在所有元素和没有元素匹配predicate时返回true。虽然这些方法总是会检查整个流,但是仍可以通过并行执行来提高速度。

四、Optional类型

高效使用Optional的关键在于,使用一个或者接受正确值、或者返回另一个替代值的方法。

创建可选值

可以选择使用Optional.of(result)或者Optional.empty()来创建一个Optional对象。

ofNullable方法被设计为null值和可选值之间的一座桥梁。如果obj不为null,那么Optional.ofNullable(obj)会返回Optional.of(obj),否则会返回Optional.empty()。

Java 8学习之Stream API的更多相关文章

  1. java 新特性之 Stream API

    强大的 Stream API 一.Stream API 的概述 Stream到底是什么呢? 是数据渠道,用于操作数据源(集合.数组等)所生成的元素序列. "集合讲的是数据,Stream讲的是 ...

  2. 恕我直言你可能真的不会java第11篇-Stream API终端操作

    一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之前 ...

  3. Java 8新特性--Stream API

    Java 8 API添加了一个新的抽象称为流Stream,以一种声明的方式处理数据,可以极大提高程序员的生产力,写出高效.干净.简洁的代码.这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可 ...

  4. Java 8新特性之旅:使用Stream API处理集合

    在这篇“Java 8新特性教程”系列文章中,我们会深入解释,并通过代码来展示,如何通过流来遍历集合,如何从集合和数组来创建流,以及怎么聚合流的值. 在之前的文章“遍历.过滤.处理集合及使用Lambda ...

  5. java8新特性——Stream API

    Java8中有两大最为重要得改变,其一时Lambda表达式,另外就是 Stream API了.在前面几篇中简单学习了Lambda表达式得语法,以及函数式接口.本文就来简单学习一下Stream API( ...

  6. java 8 学习一(概述)

    学习java8的新特性之前,简单看了下从java5开始历代版本的新特性,都是别人总结的. java5.java6.java7.java8的新特性 http://blog.csdn.net/samjus ...

  7. java9新特性-13-增强的 Stream API

    1.使用说明 Java 的 Steam API 是java标准库最好的改进之一,让开发者能够快速运算,从而能够有效的利用数据并行计算.Java 8 提供的 Steam 能够利用多核架构实现声明式的数据 ...

  8. Stream API处理集合

    使用流来遍历集合 简介 如何工作 总结 从集合或数组创建流 简介 如何工作 结论 聚合流的值 简介 如何工作 结论 转载 使用流来遍历集合 简介: Java的集合框架,如List和Map接口及Arra ...

  9. Spring WebFlux 学习笔记 - (一) 前传:学习Java 8 Stream Api (3) - Stream的终端操作

    Stream API Java8中有两大最为重要的改变:第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*). Stream 是 Java8 中处 ...

随机推荐

  1. Could not load file or assembly 'System.Data.SQLite ... 试图加载格式不正确的程序

    坑爹的System.Data.SQLite. 先给出下载地址:http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki ...

  2. .Net工程师面试笔试宝典

    .Net工程师面试笔试宝典 传智播客.Net培训班内部资料 http://net.itcast.cn 这套面试笔试宝典是传智播客在多年的教学和学生就业指导过程中积累下来的宝贵资料,大部分来自于学员从面 ...

  3. 使用jdbc的方式访问kylin cube的数据

    使用jdbc的方式访问kylin cube的数据 引用kylin相关的jar包 <dependency> <groupId>org.apache.kylin</group ...

  4. .net图表之ECharts随笔08-bar柱状图

    之前一直都是跟着修改demo,感觉用得很吃力,现在结合上配置手册就好很多了,其实说到底就是参数的配置,所以配置手册尤为重要. 当然,这其中还是很多坑,希望可以找到对应的解决方案吧!!! 1. tool ...

  5. WPF 内部Template 动画板 无法冻结此 Storyboard 时间线树供跨线程使用

    解决此问题,需要一定的想象力. 换个思路即可 大体是 使用Tag或者别无用的可以输入数值的属性,或者附加属性也可以的.来绑定到你要动画的属性 当然这个过程中要使用转换器了 我给出一个关于Button ...

  6. 【文文殿下】快速傅里叶变换(FFT)学习笔记

    多项式 定义 形如\(A(x)=\sum_{i=0}^{n-1} a_i x^i\)的式子称为多项式. 我们把\(n\)称为该多项式的次数界. 显然,一个\(n-1\)次多项式的次数界为\(n\). ...

  7. HBase二级索引的设计

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  8. bash脚本编程学习笔记(一)

    bash脚本语言,不同于C/C++是一种解释性语言.即在执行前不需要事先转变为可执行的二进制代码,而是每次执行时经解释器解释后执行.bash脚本语言是命令的堆砌,即按照实际需要,结合命令流程机制实现的 ...

  9. Using the JDBC Driver

    Download JDBC Driver This section provides quick start instructions for making a simple connection t ...

  10. 浅谈Android选项卡(三)

    上一节介绍了TabActivity的简单用法,但是现在的Api中已经不建议使用了,建议使用Fragment来替代以上的功能,下面介绍下使用Fragment和ViewPager的结合使用. http:/ ...