Stream流总结

news2024/11/26 22:17:22

前言

在Java中,涉及到对数组、Collecction等集合类中的元素进行操作的时候,通常会通过循环的方式进行逐个处理,或者使用Stream流的方式进行处理

例子

从给定句子中返回单词长度大于5的单词列表,按长度倒序输出,最多返回3个

public static List<String> sortGetTop3LongWords(@NotNull String sentence) {
    return Arrays.stream(sentence.split(","))
            .filter(word -> word.length() > 5)
            .sorted((o1, o2) -> o2.length() - o1.length())
            .limit(3)
            .collect(Collectors.toList());
}

Stream简介

Stream流操作分为3种类型:

  • 创建Stream
  • Stream中间处理
  • 终止Stream

在这里插入图片描述

每个Stream管道操作类型都包含若干个API方法,先列举下各个API方法的功能介绍

一、开始管道

主要负责新建一个Stream流,或者基于现有的数组、List、Set、Map等集合类型对象创建出新的Stream流

  • stream(): 创建出一个新的Stream串行流对象
  • parallelStream(): 创建出一个可并行执行的Stream流对象
  • Stream.of(): 通过给定的一系列元素创建一个新的Stream串行流对象

二、中间管道

负责对Stream流进行处理操作,并返回一个新的Stream对象,中间管道操作可以进行叠加

  • filter(): 按照条件过滤符合要求的元素,返回新的Stream流;
  • map(): 将已有元素转换为另一个对象类型,一对一逻辑,返回新的Stream流;
  • flatMap(): 将已有元素转换为另一个对象类型,一对多逻辑,即原来一个元素对象可能会转换为1个或者多个新类型的元素,返回新的Stream流;
  • limit(): 仅保留集合前面指定个数的元素,返回新的Stream流;
  • skip(): 跳过集合前面指定个数的元素,返回新的Stream流;
  • concat(): 将两个流的数据合并起来为1个新的流,返回新的Stream流;
  • distinct(): 对Stream流中所有元素进行去重,返回新的Stream流;
  • sorted(): 对Stream中所有的元素按照指定规则进行排序,返回新的Stream流;
  • peek(): 对Stream流中的每个元素进行逐个遍历处理,返回处理后的Stream流

三、终止管道

通过终止管道操作之后,Stream流将会结束,最后可能会执行某些逻辑处理,或者是按照要求返回某些执行后的结果数据

  • count(): 返回Stream处理后最终的元素个数
  • max(): 返回Stream处理后的元素最大值
  • min(): 返回Stream处理后的元素最小值
  • findFirst(): 找到一个符合条件的元素时则终止流处理
  • findAny(): 找到一个符合条件的元素时则推退出流处理,这个对于串行流时与findFirst相同,对于并行流比较高效,任何分片中找到都会终止后续计算逻辑
  • anyMatch(): 返回一个boolean值,类似与isContains(),用于判断是否有符合条件的元素
  • allMatch(): 返回一个boolean值,用于判断是否所有元素都符合条件
  • noneMatch(): 返回一个boolean值,用于判断是否所有元素都不符合条件
  • collect(): 将流转换为指定的类型,通过Collectors进行指定
  • toArray(): 将流转换为数组
  • iterator(): 将流转换为Iterator对象
  • foreach(): 无返回值,对元素进行逐个遍历,然后执行给定的处理逻辑

操作案例

一、map与flatMap

map与flatMap都是用于转换已有的元素为其他元素,区别点在于:

  • map必须是一对一的,即每个元素都只能转换为1个新的元素
  • flatMap可以是一对多的,即每个元素都可以转换为1个或者多个新的元素

flatMap例子:现有一个句子列表,需要将句子中每个单词都提取出来得到一个所有单词列表

public static List<String> stringToIntFlatmap() {
   List<String> sentences = Arrays.asList("hello world", "Jia Gou Wu Dao");
    return sentences.stream()
            .flatMap(sentence -> Arrays.stream(sentence.split(" ")))
            .collect(Collectors.toList());
}
stringToIntFlatmap().forEach(System.out::println);

在这里插入图片描述

这里需要补充一句,flatMap操作的时候其实是先每个元素处理并返回一个新的Stream,然后将多个Stream展开合并为了一个完整的Stream,如下:

在这里插入图片描述

二、peek和foreach方法

peek和foreach,都可以用于对元素进行遍历然后逐个的进行处理
但根据前面的介绍,peek属于中间方法,而foreach属于终止方法。这也就意味着peek只能作为管道中途的一个处理步骤,而设法直接执行得到结果,其后面必须还要有其它终止操作的时候才会被执行;而foreach作为无返回值的终止方法,则可以直接执行相关操作

public static void testPeekAndForeach() {
    List<String> sentences = Arrays.asList("hello world", "Jia Gou Wu Dao");
    // 仅peek操作,最终不会执行
    System.out.println("----before peek----");
    sentences.stream().peek(sentence -> System.out.println(sentence));
    System.out.println("----after peek----");
    // 仅foreach操作,最终会执行
    System.out.println("----before foreach----");
    sentences.stream().forEach(sentence -> System.out.println(sentence));
    System.out.println("----after foreach----");
    // peek操作后面增加终止操作,peek会执行
    System.out.println("----before peek and count----");
    sentences.stream().peek(sentence -> System.out.println(sentence)).count();
    System.out.println("----after peek and count----");
}

在这里插入图片描述

输出结果可以看出,peek独自调用时并没有被执行,但peek后面加上终止操作之后便可以被执行,而foreach可以直接被执行

避坑

这里需要补充提醒下,一旦一个Stream被执行了终止操作之后,后续便不可以再读这个流执行其他的操作了,否则会报错

public static void testHandleStreamAfterClosed() {
   List<String> ids = Arrays.asList("205","10","308","49","627","193","111", "193");
   Stream<String> stream = ids.stream().filter(s -> s.length() > 2);
   System.out.println(stream.count());
   System.out.println("-----下面会报错-----");
   // 判断是否有元素等于205
   try {
       System.out.println(stream.anyMatch("205"::equals));
   } catch (Exception e) {
       e.printStackTrace();
   }
   System.out.println("-----上面会报错-----");
}

在这里插入图片描述
因为Stream已经被执行count()终止方法了,所以多Stream再执行anyMatch方法的时候,就会报错,这里需要特别注意。

数据批量数学运算

public static void testNumberCalculate() {
   List<Integer> ids = Arrays.asList(10, 20, 30, 40, 50);
    // 计算平均值
    Double avg = ids.stream().collect(Collectors.averagingInt(value -> value));
    System.out.println("平均值:" + avg);
    // 数据统计信息
    IntSummaryStatistics summary = ids.stream().collect(Collectors.summarizingInt(value -> value));
    System.out.println("数据统计信息:" + summary);
}

上面的例子中,使用collect()方法来对list中元素值进行数学运算:结果如下:
在这里插入图片描述

并行流

机制说明

使用并行流,可以有效利用计算机的多CPU硬件,提升逻辑的执行速度。并行流通过将一整个stream划分为多个片段,然后对各个分片流并行执行处理逻辑,最后将各个分片流的执行结果汇总为一个整体流
在这里插入图片描述

约束与限制

并行流类似于多线程在并行处理,所以与多线程场景相关的一些问题同样会存在,比如死锁等问题,所以在并行流终止执行的函数逻辑,必须要保证线程安全

总结

Stream流相较于传统的foreach的方式处理stream,到底有啥优势?

根据前面的介绍,我们应该可以得出如下几点答案:

  • 代码更简洁,偏声明式的编码风格,更容易体现出代码的逻辑意图;
  • 逻辑间解耦,一个Stream中间处理逻辑,无需关注上游与下游的内容,只需要按约定实现自身逻辑即可;
  • 并行流场景效率会比迭代器逐个循环更高;
  • 函数式接口,延迟执行的特性,中间管道操作不管有多少步骤都不会立即执行,只有遇到终止操作的时候才会开始执行,可以避免一些中间不必要的操作消耗

当然了,Stream流也不全是优点,在有些方面也有其弊端:

  • 代码调测debug不便;
  • 程序员从历史写法切换到Stream流时,需要一定的适应时间

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/4156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法入门 | 分治策略

目录 分治策略 1.分治法可以解决的问题特征 2.分治法解题步骤 3.分治法编程举例 递归求阶乘 求斐波那契数列 小练习&#xff1a;给出一个数n&#xff0c;打印其每一位 分治策略 1.分治法可以解决的问题特征 &#xff08;1&#xff09;问题规模缩小到一定程度就可以轻易…

什么是HTML?

关于每篇博文的浪漫主义 【4k】镰仓的灰色与青 | irkyar | sonya74【【4k】镰仓的灰色与青 | irkyar | sonya74】 https://www.bilibili.com/video/BV14G411A7eX/?share_sourcecopy_web&vd_source385ba0043075be7c24c4aeb4aaa73352 网页 1.1什么是网页 网站是指在因特网…

重磅干货:多维度深入总结MySQL锁机制

一. 前言 有过面试经历的小伙伴都知道&#xff0c;现在面试Java开发工作&#xff0c;数据库几乎是你绕不过去的一道坎。就以文哥班上的学员为例&#xff0c;几乎每个学员的每场面试都会被问到数据库的问题。文哥很用心地给大家总结了一下&#xff0c;数据库基本都是从以下几个…

基于变化点 copula 优化算法中的贝叶斯研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

基础IO(下)——Linux

文章目录1. 理解文件系统1.2 背景知识1.2 inode vs 文件名1.3 软硬链接2. 动态库和静态库2.1 静态库.a2.1.1 如果想写一个库&#xff1f;&#xff08;编写库的人的角度&#xff09;2.1.2如果我把库给别人&#xff0c;别人怎么用呢&#xff1f;&#xff08;使用库的人的角度&…

Nature子刊:用于阿尔茨海默病痴呆评估的多模态深度学习模型

在全球范围内&#xff0c;每年有近1000万新发痴呆病例&#xff0c;其中阿尔茨海默病&#xff08;AD&#xff09;最为常见。需要新的措施来改善对各种病因导致认知障碍的个体的诊断。作者报告了一个深度学习框架&#xff0c;该框架以连续方式完成多个诊断步骤&#xff0c;以识别…

随机森林可视化

今天看到别人的文章&#xff0c;说到了随机森林可视化&#xff0c;于是尝试了下。 window安装 windows版本安装: 1.在下面去下载window的exe安装包&#xff0c;安装graphviz。 http://www.graphviz.org/download/ 在路径选项&#xff0c;点击add path to computer&#xff0c…

IDEA类和方法注释模板配置

1、类的注释模板配置 File-->Settings-->Editor-->File and Code Templates-->File --->Class: 模板代码下所示&#xff1a; /*** ClassName: ${NAME}* Author : ${USER}* Date :${DATE} ${TIME}* Description: TODO* Version :1.0*/ 上述${NAME}为类名&…

QT Android环境搭建 及 解决“Platfrom tools installed”等系列配置问题( 附QT、JDK、SDK、NDK网盘链接 )

文章目录一、安装Android相关插件二、添加JDK、SDK、NDK路径三、搭建环境过程常见问题1. “Platfrom tools installed”失败2. 以上操作全部完成且无报错现象&#xff0c;Android编译就是报错3. “SDK manger is not available with the current version of SDK tools. Use nat…

计算机网络概述

既然我们无法逃避接触互联网&#xff0c;那么为何不去了解它并且使用它。 ——因特网“之父” 温顿.瑟夫 因特网概述 1、网络、互联网与因特网的区别与关系 多节点之间通过有线链路连接起来的有线链路简单网络 节点间也可以通过无线链路连接实现无线链路简单网络 网络与网络之…

基于51单片机有害气体浓度检测超限报警Proteus仿真

资料编号&#xff1a;157 下面是相关功能视频演示&#xff1a; 157-基于51单片机有害气体浓度检测超限报警Proteus仿真(源码仿真全套资料)功能介绍&#xff1a; 采用51单片机作为CPU&#xff0c;ADC0832作为AD转换模块&#xff0c;LCD1602显示当前采集的有害气体数值&#xf…

【爬虫系列】Python 爬虫入门(1)

爬虫说明 我们知道&#xff0c;互联网时代&#xff0c;大量的数据信息会以网页作为载体而存在&#xff0c;有些公开而免费的数据比较适合采集&#xff0c;并经过有效处理之后&#xff0c;可用于数据分析、机器学习、科学决策等方面&#xff0c;而从网页中采集数据的利器&#…

<学习笔记>从零开始自学Python-之-web应用框架Django( 八)Django表单

HTML 表单是交互式网站的基本组成部分&#xff0c;用户提交信息、搜索内容、与后台数据交互都要用到表单。 1、从请求对象中获取数据 view视图函数的第一个参数都是 request,这个request就是请求获得的HttpRequest对象。里面包含中有一些关于当前所请求 URL 的信息&#xff0c…

MySQL中SQL命令语句条件查询

一、聚合函数 聚合函数&#xff1a;又叫组函数&#xff0c;用来对表中的数据进行统计和计算&#xff0c;结合group by分组使用&#xff0c;用于统计和计算分组数据 常用聚合函数 count(col)&#xff1a;求指定列的总行数max(col)&#xff1a;求指定列的最大值min(col)&#…

SnowNLP使用自定义语料进行模型训练(情感分析)

SnowNLP SnowNLP是一个功能强大的中文文本处理库&#xff0c;它囊括了中文分词、词性标注、情感分析、文本分类、关键字/摘要提取、TF/IDF、文本相似度等诸多功能&#xff0c;像隐马尔科夫模型、朴素贝叶斯、TextRank等算法均在这个库中有对应的应用。如果大家仔细观察过博主的…

nodejs的下载安装

1.从官网下载nodejs 官网地址如下 Download | Node.js 选择老版本的node防止出现兼容问题 根据电脑下载64位或者32位的 2.安装node 配置环境变量&#xff0c;nodejs安装完成后&#xff0c;会默认在系统path环境变量中配置node.exe的路径&#xff0c;打开cmd&#xff0c;输入n…

Java实现DFA算法进行敏感词过滤

一、敏感词过滤数据文件 https://github.com/jkiss/sensitive-words 代码图数据文件如下&#xff1a; 二、敏感词实现原理基于二叉树排序 首先&#xff1a;query 日 ---> {本}、query 本 --->{人、鬼子}、query 人 --->{null}、query 鬼 ---> {子}。形如下结构&…

见微知著,从两道有意思的 CSS 面试题,考察你的基础

今天在论坛&#xff0c;有看到这样一道非常有意思的题目&#xff0c;简单的代码如下&#xff1a; <div><p id"a">First Paragraph</p> </div> 样式如下&#xff1a; p#a {color: green; } div::first-line {color: blue; } 试问&#xff0…

手写笔记教会你集成Spring和Mybatis框架(有详细注解)

目录 1. 为什么要将框架进行集成呢&#xff1f; 2. 框架的集成有什么好处&#xff1f; 3. Spring框架与Mybatis框架的集成 3.1 步骤一&#xff1a; 3.2 步骤二 3.3 Spring的配置文件&#xff1a; 3.4 Mybatis的配置文件&#xff1a; 4. 总结 1. 为什么要将框架进行集成…

基于51单片机智能恒温箱控制系统Proteus仿真

资料编号&#xff1a;153 下面是相关功能视频演示&#xff1a; 153-基于51单片机智能恒温箱控制系统Proteus仿真(源码仿真全套资料)功能介绍&#xff1a; 采用51单片机作为控制CPU&#xff0c;ds18b20作为温度传感器采集温度&#xff0c;LCD1602显示当前温度&#xff0c;采用…