认识与理解java中的stream流

系列文章目录

1.SpringBoot整合RabbitMQ并实现消息发送与接收
2. 解析JSON格式参数 & 修改对象的key
3. VUE整合Echarts实现简单的数据可视化
4. List<HashMap<String,String>>实现自定义字符串排序(key排序、Value排序)
5. SpringBoot整合RabbitMQ中交换机的使用(完成消息的发送和接收案例)


文章目录

  • 系列文章目录
  • 前言
  • 一、认识stream流
    • 1.1 对比
  • 二、具体的区别
    • 2.1 普通的方式
    • 2.2 stream流
  • 三、如何运用stream流
    • 3.1 filter(Predicate):
    • 3.2 map(Function):
    • 3.3 forEach(Consumer):
    • 3.4 collect(Collector):
    • 3.5 reduce(BinaryOperator):
    • 3.6 distinct():
    • 3.7 sorted():
    • 3.8 limit(long):
    • 3.9 skip(long):
  • 总结


前言

       Stream API 是 Java 8 引入的一个用于处理集合数据的新特性。它可以让开发者以一种更函数式、更简洁的方式对集合进行操作,提供了一套丰富的中间操作和终端操作方法,可以实现过滤、映射、归约等操作,同时支持并行处理,提高了代码的可读性和性能。它的特点有很多,例如惰性求值、函数式编程方式、流水线操作、支持并行处理、内置丰富的中间(map、filter等)、终端(collect等)操作方法。
       使用 Stream API 可以简化代码,提高代码的可读性和可维护性。同时,由于其内置的并行处理功能,还可以提高代码的执行效率。在处理集合数据时,特别是需要进行复杂操作或并行处理时,Stream API 是一个非常强大和便捷的工具。下面我们就一起来学习下stream流吧~


一、认识stream流

       在前言中,已经简单的介绍了stream流的一些特点,但大家肯定光去看这写特点的话是没有什么感觉的,下面我们就直接先上一段代码,从代码带入到学习理论知识,一起去深入理解和运用stream流。

1.1 对比

我们知道,在不适用stream的情况下,同样的逻辑也可使用普通的循环去实现。那么我们就是用一个简单的方式来带入一下stream流。

我们要实现一个数组[1,2,4,5]让其每个元素的值加一,返回一个新数组
普通方法实现如下:

private List<Integer> fun2(List<Integer> list) {
        List<Integer> ss = new ArrayList<>();
        for (Integer s : list) {
            ss.add(s+1);
        }
        return ss;
    }

是用stream流实现如下:

private List<Integer> fun1(List<Integer> list) {
        List<Integer> ss=list.stream().map((key)->{
            return key+1;
        }).collect(Collectors.toList());
        return ss;
    }

打印出的效果如下图所示:
在这里插入图片描述
可以看到,最终的效果是一样的,但是究竟有什么区别的。我们在什么场景下使用哪种方式会更加好呢?这里我们就来看下他们的区别。

二、具体的区别

2.1 普通的方式

普通的循环使用于在操作简单遍历,精确控制循环控制时使用。
优点:

  • 直观性: 传统的循环方式更加直观和易于理解,适合处理简单逻辑和少量数据。
  • 精确控制: 可以精确控制循环过程,在一些特殊情况下可能更灵活。
  • 性能优化: 在某些情况下,普通的循环方式可能比Stream API更高效,尤其是对于简单的遍历和操作。

缺点:

  • 冗余代码: 普通的循环方式需要显式地进行迭代和操作,可能会导致代码量增加。
  • 不利于并行处理: 传统循环方式较难实现并行处理,无法充分利用多核处理器的优势。

2.2 stream流

需要对集合数据进行复杂的处理、筛选、转换等操作时,Stream 提供了一种更为简洁、易读和高效的方式。
优点:

  • 函数式编程风格: Stream API提供了函数式编程风格的操作,使代码更加简洁和易读。
  • 链式调用: 可以通过链式调用一系列操作来处理集合元素,减少了中间变量的使用。
  • 内置操作: Stream API提供了丰富的中间操作(如map、filter、sort等)和终端操作(如collect、forEach等),方便进行数据处理和转换。
  • 并行处理: Stream API内置支持并行处理,可以自动将任务分配到多个线程上执行,提高处理效率。

缺点:

  • 学习曲线: 对于初学者来说,可能需要一定时间来熟悉Stream API的概念和操作方式。
  • 性能开销: 在一些情况下,Stream API可能会引入额外的性能开销,尤其是在数据量很大或者处理逻辑复杂的情况下。

三、如何运用stream流

知道了优缺点后,我们来认识下常用的stream流api如何使用,下面我们一个一个理解与结合代码一起学习吧!!!

3.1 filter(Predicate):

作用:过滤符合条件的元素。
案例描述:过滤出长度大于等于 5 的字符串。
输入参数:“apple”, “banana”, “orange”, “pear”, “grape”
输出结果:[apple, banana, orange, grape]
代码如下:

private List<String> fun1(List<String> words) {
        List<String> longWords = words.stream()
                .filter(word -> word.length() >= 5)
                .collect(Collectors.toList());
        return longWords;
    }

3.2 map(Function):

作用:将元素映射为新的元素。
当使用 map 方法时,你需要传入一个 Function 对象,这个对象用于定义元素的映射关系。下面是一个简单的 Java 案例,演示如何使用 map 方法将元素映射为新的元素:

该方法案例在上述对比时的案例中有运用哦
List ss=list.stream().map((key)->{
return key+1;
}).collect(Collectors.toList());

3.3 forEach(Consumer):

作用:对每个元素执行操作。
foreach相信大家已经很熟悉了吧,当使用 forEach 方法时,你需要传入一个 Consumer 对象,这个对象用于定义对每个元素执行的操作。下面是一个简单的 Java 案例,演示如何使用 forEach 方法对集合中的每个元素执行操作:
案例:遍历list

List<String> words = Arrays.asList("apple", "banana", "orange", "pear", "grape");
//使用 forEach 方法对每个元素执行打印操作
words.forEach(System.out::println);

3.4 collect(Collector):

作用:将 Stream 元素收集到集合中。
collect(Collector) 方法是 Stream API 中用于将 Stream 元素收集到集合中的方法。通过 collect 方法,我们可以将 Stream 中的元素按照指定的规则收集到一个集合中,例如 List、Set、Map 等。
这个在上述案例中也运用到过,所以直接上代码:

List<String> longWords = words.stream()
                .filter(word -> word.length() >= 5)
                .collect(Collectors.toList());

3.5 reduce(BinaryOperator):

作用:将 Stream 元素归约为一个值。
reduce(BinaryOperator) 方法是 Stream API 中用于将 Stream 元素归约为一个值的方法。通过 reduce 方法,我们可以对 Stream 中的元素进行累积操作,最终得到一个汇总的结果。

// 创建一个包含整数的 Stream
        Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);

        // 使用 reduce 方法将 Stream 元素相加得到总和
        int sum = numbers.reduce(0, (a, b) -> a + b);

        // 输出归约后的结果
        System.out.println("Sum: " + sum); // 输出 Sum: 15

3.6 distinct():

作用:去重,去除重复元素。
distinct() 是 Stream API 中的一个方法,用于去除重复的元素,保留唯一的元素。当应用在一个 Stream 上时,distinct() 方法会返回一个包含不重复元素的新 Stream。注:一般使用Set集合解决比较好理解。

// 创建一个包含重复元素的 Stream
        Stream<String> stream = Stream.of("apple", "banana", "apple", "orange", "banana");

        // 使用 distinct 方法去除重复元素
        Stream<String> distinctStream = stream.distinct();

        // 输出去重后的元素
        distinctStream.forEach(System.out::println); // 输出 apple, banana, orange

3.7 sorted():

作用:排序,对元素进行排序。
sorted() 方法用于对 Stream 中的元素进行排序,可以使用默认的自然顺序(Comparable 接口)或者自定义排序规则(Comparator 接口)。排序后会返回一个经过排序后的新 Stream。

// 创建一个整数 Stream
        Stream<Integer> numbers = Stream.of(5, 3, 8, 1, 2);

        // 使用 sorted 方法对元素进行排序
        Stream<Integer> sortedStream = numbers.sorted();

        // 输出排序后的元素
        sortedStream.forEach(System.out::println); // 输出 1, 2, 3, 5, 8

3.8 limit(long):

作用:限制结果集的长度。
limit(long) 方法用于限制结果集的长度,只保留指定数量的元素。当应用在一个 Stream 上时,只会返回前面指定数量的元素,后面的元素将被丢弃。

 // 创建一个整数 Stream
        Stream<Integer> numbers = Stream.of(1, 2, 8, 4, 5);

        // 使用 limit 方法限制结果集的长度为3
        Stream<Integer> limitedStream = numbers.limit(3);

        // 输出限制长度后的元素
        limitedStream.forEach(System.out::println); // 输出 1, 2, 8

3.9 skip(long):

作用:跳过指定数量的元素。
skip(long) 方法用于跳过指定数量的元素,返回一个扔掉了前 n 个元素的 Stream。如果 Stream 的长度小于等于 n,则返回一个空 Stream。

// 创建一个整数 Stream
        Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);

        // 使用 skip 方法跳过前面两个元素
        Stream<Integer> skippedStream = numbers.skip(2);

        // 输出跳过元素后的结果
        skippedStream.forEach(System.out::println); // 输出 3, 4, 5

总结

       总的来说,Stream 提供了一种简洁而强大的方式来处理集合数据,它具有函数式编程的特性,能够让我们以声明性的方式进行数据处理操作。对于一些简单的api的使用其实也是比较好理解的,大家在实践中多去运用stream流的方式去处理逻辑,方便熟练运用~
       不知不觉间写文章已经快2年了,断断续续写了90多篇文章。看到大家留言我很开心,也乐意去帮助初学者去更加的深刻理解知识点。按照我的理解简单的去将知识点分享给大家。有问题大家可以联系我哦~我们一起进步

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode: 2864. 最大二进制奇数 + 模拟 + 位运算】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

HarmonyOS NEXT应用开发之深色跑马灯案例

介绍 本示例介绍了文本宽度过宽时&#xff0c;如何实现文本首尾相接循环滚动并显示在可视区&#xff0c;以及每循环滚动一次之后会停滞一段时间后再滚动。 效果图预览 使用说明&#xff1a; 1.进入页面&#xff0c;检票口文本处&#xff0c;实现文本首尾相接循环滚动&#x…

Day15 面向对象进阶——接Day14

Day15 面向对象进阶——接Day14 文章目录 Day15 面向对象进阶——接Day14一、访问修饰符二、Object三、深入String的equals()方法四、final 一、访问修饰符 1、含义&#xff1a;修饰类、方法、属性&#xff0c;定义使用的范围 2、经验&#xff1a; 2.1.属性一般使用private修…

ts--(入门到离职系列)

TS 与 JS 的区别 TypeScript[4] 是一种由微软开发的自由和开源的编程语言。它是 JavaScript 的一个超集&#xff0c;而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。-- 官方文档 说人话就是 TS 拓展了 JS 的一些功能&#xff0c;解决了 JS 的一些缺点&#…

vite配置

"vite": "^5.1.4" resolve.alias&#xff1a;配置别名 1、执行npm install -D types/node 或者 yarn add types/node -D 2、以下配置代表访问src时可以用“”代替 resolve: {alias: {"": path.resolve(__dirname, "./src"),},}, 使…

关于分布式微服务数据源加密配置以及取巧方案(含自定义加密配置)

文章目录 前言Spring Cloud 第一代1、创建config server项目并加入加解密key2、启动项目&#xff0c;进行数据加密3、实际项目中的测试server Spring Cloud Alibaba低版本架构不支持&#xff0c;取巧实现无加密配置&#xff0c;联调环境问题加密数据源配置原理探究自定义加密解…

牛客:反转链表

牛客&#xff1a;反转链表 题目描述方法一&#xff1a;代码解题思路 方法二&#xff1a;代码解题思路 题目描述 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链…

OpenHarmony开源项目—工程管理

DevEco Studio的基本使用&#xff0c;请参考DevEco Studio使用指南。本章主要介绍如何使用DevEco Studio进行多设备应用开发。 说明&#xff1a; 本章的内容基于DevEco Studio 3.1.1 Release版本进行介绍&#xff0c;如您使用DevEco Studio其它版本&#xff0c;可能存在文档与产…

【计算机网络实践】FileZilla Server1.8.1实现局域网ftp文件传输

大二新生随便写写笔记&#xff0c;轻喷&#xff0c;鉴于本人在网络搜索中并未搜索到1.8.1版本的使用方法&#xff0c;因而瞎写一页。 一、准备 下载一个FileZilla Server1.8.1在你想作为服务器的主机上&#xff08;此处直接在官网下载即可&#xff1a;Download FileZilla Serve…

【代码随想录 | 链表 04】删除链表的倒数第N个节点

文章目录 4.删除链表的倒数的第N个节点4.1题目4.2解法&#xff1a;双指针 4.删除链表的倒数的第N个节点 19.删除链表的倒数第N个节点 4.1题目 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例一&#xff1a; 输入&#xff1a;h…

公众号开篇-安利一款好用的公众号编辑器工具

前言 经过一番思索和考证&#xff0c;最终还是决定把微信公众号也捡起来。 以前没怎么搞过公众号&#xff0c;只是做了个注册并没有做后期维护和运营&#xff0c;所以这次如果要做的话也算是比较干净的从0到1的过程。 万事开头难&#xff0c;还望诸位能够多多支持&#xff0…

如何开发SDK项目,详细带领理解实践

❤ 作者主页&#xff1a;李奕赫揍小邰的博客 ❀ 个人介绍&#xff1a;大家好&#xff0c;我是李奕赫&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 记得点赞、收藏、评论⭐️⭐️⭐️ &#x1f4e3; 认真学习!!!&#x1f389;&#x1f389; 文章目录 SDK-Starter …

从汇编来角度剖析C语言函数调用过程

目录 1.引言 2.寄存器 3.栈帧 4.函数调用前调用者的动作 5.被调用者在函数调用后的动作 6.被调用者返回前的动作 7.调用者在返回后的动作 8.总结 1.引言 当一个c函数被调用时&#xff0c;一个栈帧(stack frame)是如何被建立&#xff0c;又如何被消除的。这些细节跟操作…

学习c语言:单链表的应用

一、单链表经典算法 1.1 单链表相关经典算法OJ题1&#xff1a;移除链表元素 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.…

代码随想录算法训练营Day45 ||leetCode 70. 爬楼梯 (进阶)|| 322. 零钱兑换 || 279.完全平方数

70. 爬楼梯 &#xff08;进阶&#xff09; 本质上和leetcode377一样 #include <iostream> #include <vector> using namespace std; int main() {int n, m;while (cin >> n >> m) {vector<int> dp(n 1, 0);dp[0] 1;for (int i 1; i < n; i…

图数据库基准测试 LDBC SNB 系列讲解:Schema 和数据生成的机制

LDBC&#xff08;Linked Data Benchmark Council&#xff09;Social Network Benchmark&#xff0c;简称 LDBC SNB&#xff0c;是一种针对社交网络场景的评估图数据库性能的基准测试。 LDBC 简介 除了 Social Network Benchmark&#xff0c;LDBC 旗下目前还有其他几种基准测试…

隧道技术和代理技术(三)

隧道技术 知识点 -隧道技术&#xff1a;解决不出网协议上线的问题&#xff08;利用出网协议进行封装出网&#xff09; -代理技术&#xff1a;解决网络通讯不通的问题&#xff08;利用跳板机建立节点后续操作&#xff09; 内环境示意图&#xff0c;方便理解 思路&#xff1a;…

C语言例2-3:从键盘输入一个正整数(位数小于或等于10),判断其是否是回文数

回文数是将自然数n的各位数字反向排列得到自然数n1&#xff0c;若n1与n相等&#xff0c;则称为回文数&#xff0c;例如12321 //从键盘输入一个正整数&#xff08;位数小于或等于10&#xff09;&#xff0c;判断其是否是回文数 //回文数是将自然数n的各位数字反向排列得到自然数…

企业信息化转型之企业统一门户搭建

一、当前企业门户实施的背景和痛点 企业随着公司业务的发展&#xff0c;公司运作的复杂度在不断加大&#xff0c;各部门的业务量和业务的复杂度都在不断增加&#xff0c;已经建设了ERP、HR、OA、考勤、合同、BPM、PLM等有效地支撑了过去和现有业务的发展。 企业在信息化办公是…

一款强大的逆向分析工具,开源!

工具介绍 Ghidra 是由美国国家安全局&#xff08;NSA&#xff09;研究部门开发的软件逆向工程&#xff08;SRE&#xff09;套件&#xff0c;用于支持网络安全任务。包括一套功能齐全的高端软件分析工具&#xff0c;使用户能够在各种平台(Windows、Mac OS和Linux)分析编译后的代…