Java - Stream流详解

news2024/12/23 22:53:45

文章目录


前言

大家好,好久不见了,最近由于实训的影响导致拖更了,在更新这一次估计javaSE基本上就算是完结了,还有一些落下的后面也会补上的,下次见面就是数据结构了

尽情期待吧!那么就让我们步入Stream流的学习吧! 

 


一、Stream流是什么?

Stream流是Java 8中的一个新特性,它提供了一种处理集合和数组的方式。Stream流可以让我们以一种更加简洁、高效、可读性更强的方式来处理数据。Stream流可以用于过滤、映射、排序、聚合等操作,它可以让我们避免使用循环和条件语句来处理数据,从而让代码更加简洁易懂。Stream流的操作可以分为中间操作和终止操作两种类型,中间操作返回的是一个新的Stream流,终止操作返回的是一个非Stream类型的结果。Stream流的处理是惰性求值的,只有在执行终止操作时才会开始处理数据。

流(Stream)是一种基于支持一次性处理数据的数据源的元素序列,流只能使用一次。

流的设计初衷是为了支持函数式编程,它的目的是将数据处理和数据存储分离开来,使得数据处理更加灵活和高效。因此,流的元素只是在流中传递的临时数据,它们并不是永久存储在内存中的数据。当流的元素被消费后,它们就会被释放,不能再次使用.

如果需要对同一个数据集进行多次不同的操作,可以使用流的中间操作方法来构建多个流管道,每个流管道都可以对流进行不同的操作,并返回一个新的流。这样就可以对同一个数据集进行多次操作,而不需要重新获取数据集。

二、流的分类

顺序流

顺序流是一种单线程的流,它按照数据流的顺序依次处理每个元素,每个元素的处理都必须等待上一个元素的处理完成才能开始。

并行流

并行流是一种多线程的流,它可以将数据分成多个部分并行处理,每个部分都可以在不同的线程中处理,从而提高处理效率。

使用顺序流可以保证数据处理的顺序和一致性,适用于处理数据量较小的情况。而使用并行流可以提高数据处理的速度,适用于处理数据量较大、处理时间较长的情况。但是并行流也有一些缺点,比如线程之间的通信和同步会带来额外的开销,而且并行流可能会影响数据的顺序和一致性。因此在使用并行流时需要注意线程安全和数据一致性等问题。

区别

顺序流和并行流的区别在于它们的处理方式不同,顺序流是单线程的,而并行流是多线程的。使用的方法也有一些区别,例如:

  1. 获取顺序流:可以使用集合类的stream()方法、Arrays类的stream()方法、Stream类的of()方法、Stream类的iterate()方法、Stream类的generate()方法、Files类的lines()方法等来获取顺序流。

  2. 获取并行流:可以使用集合类的parallelStream()方法、Stream类的of()方法的parallel()方法、Stream类的iterate()方法的parallel()方法、Stream类的generate()方法的parallel()方法等来获取并行流。

除此之外,顺序流和并行流的使用方法基本相同,例如可以使用map()、filter()、reduce()等方法对流进行操作。但需要注意的是,在使用并行流时需要考虑线程安全和数据一致性等问题。

下面我只会详细讲解顺序流的使用,并行流的使用大差不差,大家有兴趣可以自行尝试

三.获取流的常用方式

前面提到过,流(Stream)是一种基于支持一次性处理数据的数据源的元素序列,流只能使用一次

所以将流保存起来没有任何意义,但是获取还是很有必要的,下面我会将常用的获取方式详解,不常用的也会给出获取方式,大家有兴趣的话可以自行尝试!

对了,我觉得有必要的是因为我现在的知识面不广,接触不到太复杂的内容,等回头成了大牛再来补

哈哈,其实不说的大部分是我不会,小黑子,漏出鸡脚了吧

1.通过集合获取流:可以使用集合类中的stream()方法或parallelStream()方法来获取流

2.通过数组获取流:可以使用Arrays类中的stream()方法来获取流。

3.通过Stream.of()方法获取流:可以使用Stream类中的of()方法来获取流。

4.通过Stream.iterate()方法获取流:可以使用Stream类中的iterate()方法来获取流

Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5); // 获取顺序流

5.通过Stream.generate()方法获取流:可以使用Stream类中的generate()方法来获取流

Stream<Double> stream = Stream.generate(Math::random).limit(5); // 获取顺序流

 6.通过Files.lines()方法获取流:可以使用Files类中的lines()方法来获取流。

Stream<String> stream = Files.lines(Paths.get("file.txt")); // 获取顺序流

1.通过集合获取流

 可变参数不懂得详见http://t.csdn.cn/SSp8u

 源码

 

 刚才看了一下,有点麻烦,先欠着吧

大家暂时知道获取的这个方法就行了

2.通过数组获取流

 源码

3.通过Stream.of()方法获取流

 

四.常用方法用法

  1. filter(Predicate<T> predicate):过滤流中的元素,只保留符合条件的元素。
  2. map(Function<T, R> mapper):将流中的元素按照指定的方式进行映射,返回一个新的流。
  3. flatMap(Function<T, Stream<R>> mapper):将流中的元素按照指定的方式进行映射,然后将所有映射结果合并成一个流。
  4. limit(long maxSize):截取流中的前maxSize个元素。
  5. skip(long n):跳过流中的前n个元素。
  6. sorted():对流中的元素进行排序。
  7. distinct():去重,去除流中重复的元素。
  8. forEach(Consumer<T> action):对流中的每个元素执行指定的操作。
  9. reduce(T identity, BinaryOperator<T> accumulator):将流中的元素按照指定的方式进行累加,返回一个Optional对象。
  10. collect(Collector<T, A, R> collector):将流中的元素收集到一个集合中。
  11. concat 合并a和b两个流为一个流

标红的不会进行讲解,有的是在我能力范围之外,当然了有两个,哈哈,主要是懒,不想了解

值得一提的是第六个排序好像可以指定排序规则,我去试试哈

确实可以哈

大家有兴趣可以试试,关于排序我之前的博文讲解的已经很透彻了,不再赘述

下面我只会简单演示一下,想要掌握的自己可以去练一下哈,到最后我会附上练习题和答案

1.filter(Predicate<T> predicate):过滤流中的元素,只保留符合条件的元素

2.limit  &&  skip

 3.distinct():去重,去除流中重复的元素。

 4.concat 合并a和b两个流为一个流

5. map(Function<T, R> mapper):将流中的元素按照指定的方式进行映射,返回一个新的流

 突然想到这个问题了,解释一下

 6.forEach(Consumer<T> action):对流中的每个元素执行指定的操作。

 就目前来看,我用的最多的是遍历

大家只要掌握遍历即可

7.collect(Collector<T, A, R> collector):将流中的元素收集到一个集合中。

 

 5.练习

0,过滤奇数,只留下偶数

ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);

1,男演员只要名字为3个字的前两人
2,女演员只要姓杨的,并且不要第一个
3,把过滤后的男演员姓名和女演员姓名合并到一起
4,将上一步的演员信息封装成Actor对象。
5,将所有的演员对象都保存到List集合中。

备注:演员类Actor,属性有:name,age
男演员:  "蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27"
女演员:  "赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33"
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<String> list2 = new ArrayList<>();

        Collections.addAll(list1,"蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27");
        Collections.addAll(list2,"赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33");

        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);

        // 0, 过滤奇数,只留下偶数

        List<Integer> collect = list.stream().filter(integer -> integer % 2 == 0).collect(Collectors.toList());

        System.out.println(collect);

        // 1,男演员只要名字为3个字的前两人

        Stream<String> stream1 = list1.stream().filter(s -> s.split(",")[0].length() == 3).limit(2);

        //  2,女演员只要姓杨的,并且不要第一个

        Stream<String> stream2 = list2.stream().filter(s -> s.startsWith("杨")).skip(1);

        // 3,把过滤后的男演员姓名和女演员姓名合并到一起

        //Stream.concat(stream1,stream2).forEach(s-> System.out.println(s));

        // 4,将上一步的演员信息封装成Actor 对象

        // 类型转换 String-> Actor
        Stream.concat(stream1, stream2).map(new Function<String, Actor>() {
            @Override
            public Actor apply(String s) {
                Actor actor = new Actor();

                actor.setName(s.split(",")[0]);

                actor.setAge(Integer.parseInt(s.split(",")[1]));

                return actor;
            }
        }).forEach(s-> System.out.println(s.getName()+" "+s.getAge()));

        // 5,将所有的演员对象都保存到List集合中。
        List<Actor> list3 = Stream.concat(stream1, stream2).map(s -> new Actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])))
                .collect(Collectors.toList());

        System.out.println(list3);

总结

今天就说到这吧,大家记得做练习哈

 

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

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

相关文章

【openEuler 20.03 TLS编译openGauss2.0.0源码】

openEuler 20.03 TLS编译openGauss2.0.0源码 一、安装环境二、安装前准备二、安装步骤 一、安装环境 项目Value操作系统openEuler 20.03 64bit with ARMopenGauss2.0.0openGauss-third_party2.0.0 二、安装前准备 项目Value购买华为ECS鲲鹏 8vCPU32G 100M/s带宽 openEuler 2…

使用CubeMX配置STM32驱动HC-SR04超声波模块

文章目录 前言1 使用STM32CubeMX初始化代码1.1 时钟配置1.2 设置定时器1.3 触发引脚1.4 串口配置 2 代码编写2.1 添加驱动文件2.2 修改main.c 3 实现效果参考 前言 硬件选择 stm32f103c8t6&#xff08;最小板&#xff09;hc-sr04超声波模块 软件环境 stm32cubeIDE 1.12.1 …

【Linux】TCP网络套接字编程+协议定制+序列化和反序列化

悟已往之不谏&#xff0c;知来者之可追。抓不住的就放手&#xff0c;属于你的都在路上…… 文章目录 一、TCP网络套接字编程1.日志等级分类的日志输出API2.单进程版本的服务器客户端通信3.多进程版本和多线程版本4.线程池版本5.守护进程化的线程池服务器6.三次握手和四次挥手的…

python编程——pycharm的安装与使用

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 本文专栏&#xff1a;python专栏 专栏介绍&#xff1a;本专栏为免费专栏&#xff0c;并且会持续更新python基础知识&#xff0c;欢迎各位订阅关注。 目录 一、python IDLE的使用 二、pycharm的安装与使用 1、…

十分钟带你看懂——Python测试框架之pytest最全讲

pytest特短 pytest是一个非常成熟的全功能的Python测试框架&#xff0c;主要有以下几个特点&#xff1a; 简单灵活&#xff0c;容易上手 支持参数化 能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08…

重磅版本发布|三大关键特性带你认识 Milvus 2.2.9 :JSON、PartitionKey、Dynamic Schema

亮点颇多、精彩程度堪比大版本的 Milvus 2.2.9 来啦&#xff01; 随着 LLM 的持续火爆&#xff0c;众多应用开发者将目光投向了向量数据库领域&#xff0c;而作为开源向量数据库的领先者&#xff0c;Milvus 也充分吸收了大量来自社区、用户、AI 从业者的建议&#xff0c;把重心…

非常简单就能理解的 链表带环问题 你也能轻松学会!

文章目录 判断链表是否带环若链表带环找出环的入口其他高频的面试问题 判断链表是否带环 题目描述&#xff1a; 给定一个链表&#xff0c;判断链表中是否有环。 思路&#xff1a; 可以明确的是&#xff1a;若一个链表带环&#xff0c;那么用指针一直顺着链表遍历&#xff0c…

《嵌入式系统》知识总结10:使用位带操作操纵GPIO

位操作 汇编层面 外设控制常要针对字中某个位&#xff08;Bit&#xff09;操作 以字节编址的存储器地址空间中&#xff0c;需要3步骤&#xff08;读出-修改-写回&#xff09; 1.&#xff08;从外设&#xff09;读取包含该位的字节数据 2. 设置该位为0或1、同时屏蔽其他位&am…

微信小程序 <view></view>容器嵌套,wxss样式修改内部内部样式不产生效果

网上关于”微信小程序讲的知识很少“&#xff0c;微信开发文档对于新手不是很友好&#xff0c;但是建议一定要学会看文档。 问题如下&#xff1a; 我写了好几个<view></view> 容器嵌套&#xff0c;我在对内部容器包括的内容做修改时&#xff0c;不产生效果&#…

apache RocketMQ远程代码执行(CVE-2023-33246)

RocketMQ是阿里巴巴在2012年开发的分布式消息中间件&#xff0c;专为万亿级超大规模的消息处理而设计&#xff0c;具有高吞吐量、低延迟、海量堆积、顺序收发等特点。它是阿里巴巴双十一购物狂欢节和众多大规模互联网业务场景的必备基础设施。 RocketMQ的NameServer、Broker、…

【计算机网络之HTTP篇】Cookie与Session的区别

目录 Cookie 原理 缺点 Session 原理 区别 Cookie cookie是浏览器在本地存储数据的一种机制。 原理 当浏览器向服务器第一次发送请求时&#xff0c;服务器会向浏览器返回一个Cookie&#xff0c;此时 cookie记录着浏览器访问服务器的用户登录状态。 后续浏览器再次访问服…

[深度学习入门案例1]基于Keras的手写数字图像识别

文章目录 一、工具与环境 二、深度学习环境的搭建 1.安装Anaconda 2.创建虚拟环境 第1步&#xff1a;打开Anaconda的命令窗口&#xff0c;即Anaconda Prompt 第2步&#xff1a;使用命令创建指定版本的python环境&#xff08;这里以py36命令环境名称举例&#xff09; 3.切换…

深度解析MethodHandle方法句柄之findspecial方法的原理

网上看过太多关于MethodHandle方法句柄的文章&#xff0c;但是基本上没有人能把其中的findspecial方法讲清楚&#xff0c;特别是findspecial的第四个参数specialCaller, 相信大家都不明白是干嘛用的&#xff0c;网上给出的水文是很多都是说&#xff1a; 执行到specialCaller的父…

kafka二

练一练 需求&#xff1a;写一个生产者&#xff0c;不断的去生产用户行为数据&#xff0c;写入到kafka的一个topic中 生产的数据格式&#xff1a; 造数据 {"guid":1,"eventId":"pageview","timestamp":1637868346789} isNew 1 {&quo…

面了一个32岁的程序员,只因这一点,一眼看穿是培训班出来的,简历都是假的.....

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

Kafka安装及架构

kafka的特点 高吞吐量、低延迟&#xff1a;kafka每秒可以处理几十万条消息&#xff0c;它的延迟最低只有几毫秒&#xff0c;每个topic可以分多个partition, 由多个consumer group 对partition进行consume操作。可扩展性&#xff1a;kafka集群支持热扩展持久性、可靠性&#xf…

机智云的离线语音识别模组,让家电变得更加智能和便捷

随着人们对智能化生活的需求不断增加&#xff0c;离线语音模组越来越受到欢迎。它可以为家庭、工作和娱乐提供更加智能和便捷的服务&#xff0c;例如通过语音指令控制家居设备、查询天气信息、播放音乐等。 “小智同学&#xff0c;打开灯光” “调到最亮” “正转一档” 人工智…

Golden Gate (GGX) ZK 预编译: 彻底改变游戏玩法,成本降低千倍

Golden Gate (GGX) 作为一种新型跨链基础设施协议&#xff0c;解决了困扰 Web3.0 Layer1 和 Layer2 的跨链通信和流动性转换难题。 其解决方案主要涉及两个核心: 1) 与协议无关的通信&#xff0c;可以实现主流标准消息的传递&#xff0c;包括 IBC、XCMP 和 LayerZero 等标准。 …

2023 华为 Datacom-HCIE 真题题库 10/12--含解析

单项选择题 1.[试题编号&#xff1a;190585] &#xff08;单选题&#xff09;华为SD-WAN解决方案中&#xff0c;当CPE位 于NAT设备后的私网时&#xff0c;特别是两个站点的CPE同时位于NAT设备后的私网时&#xff0c;CPE之 间需要使用NAT穿越技术。华为SD-WAN解决方案中使用以下…

驱动开发--根文件系统

1、单片机开发属于嵌入式开发吗&#xff1f; 广义&#xff1a;单片机开发属于嵌入式开发---&#xff08;嵌入式微处理器开发&#xff09; 一般不带mmu&#xff08;地址映射&#xff09; 狭义&#xff1a;单片机开发不属于嵌入式 ---&#xff08;Linux嵌入式开发&#xff09;一…