前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

上一篇讲解到了Lambda表达式的使用《最近学到的Lambda表达式基础知识》,还没看的同学可以先去阅读一下哈~

相信也有不少的同学想要知道:Lambda表达式在工作中哪个场景会用得比较多?跟Lambda搭边的,使用Stream流会比较多

一般人第一次看Stream流的代码,都会有点看不懂(它的代码看起来好像就不是写Java一样.),希望这篇文章能带大家入个门

一、体验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流分为三步:

  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流,至于中间操作、最终操作的API讲解我就不写了(网上的教程也很多)

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

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

参考资料:

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,关注即可获取!

觉得我的文章写得不错,点

手把手带你体验Stream流的更多相关文章

  1. 手把手带你体验鸿蒙 harmonyOS

    wNlRGd.png 前言 本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍: 我的 GIthub 博客 学习导图 image.png 一.为什么要尝鲜 harmonyos? wNlfx ...

  2. Jquery扩展-手把手带你体验

    Jquery扩展是在项目中经常用到的,有时候为了提取一些公共方法,有时候为了模块化管理等等,下面我们来体验一下.当然扩展离不开Jquery几个基础方法 1:$.extend() 2:$.fn.func ...

  3. .net中的"异步"-手把手带你体验

    周二刚过,离5.1小长假还有那么一阵,北京的天气已经开始热起来了.洗完澡,突然想起博客园一位大哥暂称呼元哥吧,当时我写了一篇windows服务的安装教程(http://www.cnblogs.com/ ...

  4. Sqlserver作业-手把手带你体验

    所谓Sql Server作业就是按照规定的时间执行指定的脚本,如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理-SQL Server代 ...

  5. Windows服务-手把手带你体验

    Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而 ...

  6. 30.Stream流

    5.Stream流 5.1体验Stream流[理解] 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 把集合中所有以"张"开头的元素存储到一个新的集 ...

  7. JavaSE23-函数式接口&Stream流

    1.函数式接口 1.1 函数式接口概述 概念 有且仅有一个抽象方法的接口 如何检测一个接口是不是函数式接口 @FunctionalInterface 放在接口定义的上方:如果接口是函数式接口,编译通过 ...

  8. 【重学Java】Stream流

    Stream流 体验Stream流[理解] 案例需求 按照下面的要求完成集合的创建和遍历 创建一个集合,存储多个字符串元素 把集合中所有以"张"开头的元素存储到一个新的集合 把&q ...

  9. Java 8 新特性之 Stream 流基础体验

    Java 8 新特性之 Stream 流基础体验 package com.company; import java.util.ArrayList; import java.util.List; imp ...

随机推荐

  1. Erlang模块gen_tcp翻译

    概述 TCP/IP套接字接口 描述 gen_tcp模块提供了使用TCP / IP协议与套接字进行通信的功能. 以下代码片段提供了一个客户端连接到端口5678的服务器的简单示例,传输一个二进制文件并关闭 ...

  2. Leetcode:合并两个有序链表

    class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) { return ...

  3. 055 Python第三方库安装

    目录 一.概述 二.看见更大的Python世界 2.1 Python社区 2.1.1 PyPI 2.1.2 实例:开发与区块链相关的程序 2.2 安装Python第三方库 三.第三方库的pip安装方法 ...

  4. 〈一〉ElasticSearch的介绍

    目录 什么是ElasticSearch 核心能力 ES的搜索核心 搜索引擎选择 搜索的处理 补充: 小节总结: 基本学习环境搭建 如何操作ElasticSearch 下载.安装和运行(Based Wi ...

  5. jupyter lab(notebook)相关配置

    安装的是Anaconda3(Python 3.6.4),自带的版本较低,这里升级版本conda update jupyterlab 一.配置jupyter lab(notebook)远程访问 1.1 ...

  6. JAVA内存模型与JVM内存结构

    问题:什么事java内存模型? 首先呢不要答堆.栈.方法区.这是JVM的内存结构.下面阐述了JMM和JVM的区别和自己对JMM的见解 1.Java内存模型(JMM):即多线程相关的.定义了一个线程对另 ...

  7. python常用内建模块——datetime

    datetime是python处理日期和时间的标准库. 获取当前日期和时间 >>>from datetime import datetime >>>now = da ...

  8. spring data jpa介绍

    首先了解JPA是什么? JPA(JavaPersistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.他的出现主 ...

  9. ios 各个手机型号尺寸及分辨率适配

    常用宏 // 判断是否是ipad #define isPad ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdio ...

  10. Java8之熟透Optional

    一.使用Optional引言 1.1.代码问题引出 在写程序的时候一般都遇到过 NullPointerException,所以经常会对程序进行非空的判断: User user = getUserByI ...