专栏首页程序员的成长之路手把手带你体验Stream流

手把手带你体验Stream流

程序员的成长之路

互联网/程序员/成长/职场

阅读本文大概需要 4 分钟。

一、体验Stream流

大家在自学时,大多数会学过一个程序:算出从数组元素的和,当时我们是怎么写的?一般来说是这样的:

public static void main(String[] args) {
    int[] nums = { 1, 2, 3 };
    int sum = 0;
    for (int i : nums) {
        sum += i;
    }
    System.out.println("结果为:" + sum);
}

如果我们使用Stream流的话,可以这样:

public static void main(String[] args) {
    int[] nums = { 1, 2, 3 };
    int sum2 = IntStream.of(nums).sum();
    System.out.println("结果为:" + sum2);
}

代码量上可以明显看出,用Stream流的方式会少一些。

我理解的Stream流编程就是:某些场景会经常用到操作(求和/去重/过滤….等等),已经封装好API给你了,你自己别写了,调我给你提供的API就好了

1.1 支持并发

回到我们最原始的代码:

public static void main(String[] args) {
    int[] nums = { 1, 2, 3 };
    int sum = 0;
    for (int i : nums) {
        sum += i;
    }
    System.out.println("结果为:" + sum);
}

如果我们想要for循环的内部支持并发的话,显然不太好去写。但使用Stream流的方式,调用一个方法就可以支持并发(parallel):

public static void main(String[] args) {
    int[] nums = { 1, 2, 3 };
    int sum2 = IntStream.of(nums).parallel().sum();
    System.out.println("结果为:" + sum2);
}

优点:调API肯定是比自己写的代码量要少。 缺点:不方便调试

为什么要使用Stream流在我看来就是以上两个原因:

  • 方便并发
  • 代码量少(直接调用API)

二、如何使用Stream流?

Stream继承结构图

使用Stream流分为三步:

  1. 创建Stream流
  2. 通过Stream流对象执行中间操作
  3. 执行最终操作,得到结果

三步走

2.1 创建流

创建流我们最常用的就是从集合中创建出流

/**
 * 返回的都是流对象
 * @param args
 */
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    // 从集合创建
    Stream<String> stream = list.stream();
    Stream<String> stream1 = list.parallelStream();

    // 从数组创建
    IntStream stream2 = Arrays.stream(new int[]{2, 3, 5});

    // 创建数字流
    IntStream intStream = IntStream.of(1, 2, 3);

    // 使用random创建
    IntStream limit = new Random().ints().limit(10);

}

2.2 执行中间操作

怎么理解中间操作?意思是这样的:在上面我们已经能创建出Stream了,我们是对Stream进行操作,对Stream操作返回完返回的还是Stream,那么我们称这个操作为中间操作。

中间操作 解释

比如,我们现在有个字符串my name is 007,代码如下:

String str = "my name is 007";

Stream.of(str.split(" ")).filter(s -> s.length() > 2)
    .map(s -> s.length()).forEach(System.out::println);

分解:

1、从字符串数组创建出流对象:

Stream<String> split = Stream.of(str.split(" "));

2、通过流对象的API执行中间操作(filter),返回的还是流对象:

Stream<String> filterStream = split.filter(s -> s.length() > 2);

3、通过返回的流对象再执行中间操作(map),返回的还是流对象:

Stream<Integer> integerStream = filterStream.map(s -> s.length());

因为中间操作返回的都是流对象,所以我们可以链式调用

注意:Stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行(惰性求值)。

比如说,peek()是一个中间操作,返回的是Stream流对象,只要它不执行最终的操作,这个Stream是不会执行的。

String str = "my name is 007";
Stream.of(str.split(" ")).peek(System.out::println); // 不会有信息打印

2.3 执行最终操作

最终操作返回的不再是Stream对象,调用了最终操作的方法,Stream才会执行。还是以上面的例子为例:

String str = "my name is 007";
Stream.of(str.split(" ")).peek(System.out::println).forEach(System.out::println)

这次我们加入了最终操作,所以这次的Stream流会被执行,由于中间操作和最终操作都是执行打印,所以会看到两次打印:

结果图

至于中间操作和最终操作怎么区分,我们以返回值来看就行了。中间操作返回的是Stream实例对象,最终操作返回的不是Stream实例对象:

Stream接口的方法

最后

这篇文章主要跟大家一起初步认识一下Stream流,至于中间操作、最终操作的API讲解我就不写了(网上的教程也很多)

使用Stream的原因我认为有两个:

  1. JDK库提供现有的API,代码写起来简洁优化
  2. 方便并发。大家可以记住一个结论:在多核情况下,可以使用并行Stream API来发挥多核优势。在单核的情况下,我们自己写的for性能不比Stream API 差多少

本文分享自微信公众号 - 程序员的成长之路(cxydczzl)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Flyway 助力数据库脚本自动化管理攻略

    今天,探讨一个有趣的话题:我们可以通过 Git 来实现项目版本控制;通过 Jenkins 进行持续集成,那么对于数据库层面,我们仍然依赖于纯手工运行 SQL 脚...

    用户2781897
  • 安居客 Android APP 走向平台化

    安居客 Android App 距离上次的模块化/组件化重构已经两年多了,重构之后很好的支撑了两年多以来的业务发展。但这个世界总是在向前走的,没有任何一种架构能...

    张磊BARON
  • 详述一则DB2 Error Code 1639和SQL State 08001案例诊断和解决方案

    导读:在 db2inst1/sqllib/security 目录下,检查 db2ckpw 和 db2chpw 文件的权限。

    数据和云
  • Redis高级客户端Lettuce详解

    Lettuce是一个Redis的Java驱动包,初识她的时候是使用RedisTemplate的时候遇到点问题Debug到底层的一些源码,发现spring-dat...

    猿天地
  • Java 14 可能带来什么新特性?

    JDK/Java 13 在一个月前已经发布,该版本带来了 5 大新特性,笔者观察到其中的 Text Blocks(文本块)特性似乎被讨论最多。文本块特性与常见的...

    搜云库技术团队
  • 五分钟学算法小知识:用栈实现队列/用队列实现栈

    这两种数据结构底层其实都是数组或者链表实现的,只是 API 限定了它们的特性,那么今天就来看看如何使用「栈」的特性来实现一个「队列」,如何用「队列」实现一个「栈...

    五分钟学算法
  • 为什么建议使用你 LocalDateTime ,而不是 Date?

    来源:juejin.im/post/5d7787625188252388753eae

    用户1516716
  • python lxml中etree的简单应用

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    于小勇
  • 测试开发进阶(二十九)

    rest_framework.generics.ListCreateAPIView

    zx钟
  • 测试开发进阶(二十八)

    进入 get_object_or_404可以看到一个解包,这样就拿到了查询集中 id=1的内容

    zx钟

扫码关注云+社区

领取腾讯云代金券