Stream流操作

news/2025/1/22 15:37:21/文章来源:https://www.cnblogs.com/crowing-bird/p/18686197

Stream流操作

一、过滤

估计很多人学习stream流大部分是从filter 方法开始,该方法筛选出满足条件的数据组成一个新的流。我们从示例中感觉一下该方法的作用。

		List<Integer> numbers = Arrays.asList(1,4,2,5,3,7,120,60,54,88,88,90,11);List<Integer> list = numbers.stream().filter(i -> i > 18)  //筛选出大于18的数据//.distinct().collect(Collectors.toList());System.out.println(list);
打印信息[120, 60, 54, 88, 88, 90]

从打印信息中可看出确认筛选出了满足条件的数据。

二、去重

distinct 方法,将会计算流中元素所生成的hashCode和equals方法,剔除重复的数据示例如下。

		List<Integer> numbers = Arrays.asList(1,4,2,5,3,7,120,60,54,88,88,90,11);List<Integer> list = numbers.stream().filter(i -> i > 18).distinct() //去除重复.collect(Collectors.toList());System.out.println(list);打印信息[120, 60, 54, 88, 90]

此代码块与过滤代码块内容基本一样,唯一不同点把distinct() 注释去除,执行distinct()方法。注意跟过滤代码块的打印信息对比,过滤代码块打印信息有重复两个88数据。去重代码块每个打印数据是唯一的。

三、截取

limit(long maxSize)方法,将会按传递过来的长度,截取流数据。示例如下。

	List<Integer> numbers = Arrays.asList(1,4,2,5,3,7,120,60,54,88,88,90,11);List<Integer> list = numbers.stream().filter(i -> i > 18).limit(1).collect(Collectors.toList());System.out.println(list);
打印信息[120]

本示例中,满足大于18的元素不止一个,最后只打印了一个数据,表示截取成功。

四、跳过

skip(long n),跳过n个元素后往下执行。代码如下。

	List<Integer> numbers = Arrays.asList(1,4,2,5,3,7,120,60,54,88,88,90,11);List<Integer> list = numbers.stream().filter(i -> i > 18)//.skip(2).collect(Collectors.toList());System.out.println(list);注释代码skip(2) 打印信息[120, 60, 54, 88, 88, 90]取消注释执行skip(2)打印信息[54, 88, 88, 90]

代码示例中执行skip(2),跳过2个元素。从打印信息中可看出跳过了120,60两个元素。

五、映射

map 方法,将一个元素转换为另一个类型的元素。接收一个Function 接口(lambda函数)作数据转换逻辑。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class Person {private String name;private int age;public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public static void main(String[] args) {List<Person> persons = Arrays.asList(new Person("张三",22),new Person("李四",50));List<String> names =  persons.stream().map(p -> p.getName()).collect(Collectors.toList());System.out.println(names);}}打印信息 
[张三, 李四]

从方法中可看出。通过map 方法,将取出name属性生成一个字符串流集合(Person 对象转换(映射)成 String 对象)。

六、多级流转化为平级流

flatMap方法,如果一个流中,包含了流,可以通过该方法将每个元素转化为流。最后将所有的流合并为一个。同map的方法其它还是蛮像的,区别在于flatMap 方法必须强制将元素将化为流。查看方法的签名如下。

Stream map(Function<? super T, ? extends R> mapper)

Stream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

从签名中可知,flatMap 的转换函数接口Function,第二个转换后的对象(? extends Stream<? extends R>)可知,必须强制继承Stream,即一定是流的子类。

示例代码如下。

List<List<String>> list = Arrays.asList(Arrays.asList("a"),Arrays.asList("b"),Arrays.asList("c"),Arrays.asList("d"));
System.out.println("list原始数据打印: " + list); 
System.out.println("list转换后打印,形成了一个平级流: "+list.stream().flatMap(items -> Arrays.stream(items.toArray(newString[0]))).toList());打印信息
list原始数据打印: [[a], [b], [c], [d]]  //原始对象,打印对象里面是多个数组。
list转换后打印,形成了一个平级流: [a, b, c, d]   //转换后为平级的数据。
七、流中至少有一个元素满足条件

anyMatch方法匹配是否有元素是否满足要求,如果满足要求,马上停止返回,即只要确定有一个元素满足要求,即停止检查。示例代码如下。

        boolean status = Arrays.asList(1,2,3,4,5).stream().anyMatch(i -> {System.out.print(i  +"、") ;return i >= 3;});System.out.println();System.out.println(status);打印信息1、2、3、true

从代码中可知,anMatch匹配条件为元素大于等于3的数据。有3,4,5满足条件。只打印信息只打印到3就停止了,即只要有一个元素满足条件,即停止循环,马上返回。打印的返回状态status也为true

八、流中所有元素都满足条件

allMatch 所有的元素都满足条件时才会返回true,不满足条件马上停止循环,返回false。示例代码如下。

boolean status = Arrays.asList(1,2,3,4,5).stream().allMatch(i -> {System.out.print(i  +"、") ;return i >= 3;});System.out.println();System.out.println(status);打印信息如下1、false

跟前一个示例基本一致,只是将anyMatch替换为allMatch。

九、流中所有的元素都不满足条件

noneMatch方法所有的元素都不满足条件返回true,与allMatch 方法相对。示例代码如下。

boolean status = Arrays.asList(1,2,3,4,5).stream().noneMatch(i -> {System.out.print(i  +"、") ;return i >= 6;});System.out.println();System.out.println(status);打印信息1、2、3、4、5、true

跟前一个示例基本一致,只是将allMatch替换为noneMatch。

十、查找(获取元素)元素

查找元素(返回一个元素)有findAny和findFirst方法,两个方法都返回一个Optional 对象(jdk8新增的空处理类)。区别findAny返回的值有一定的随机性,findFirst只会返回流中的第一个元素。

		List<Integer> numbers = new ArrayList<> (Arrays.asList(1,4,3,2,6,5,8,11,9,15,10,12,7)); //创建集合for(int i=0;i<5;i++) {int num = numbers.parallelStream().filter(j -> j > 5).findAny().get(); //获取随机的一个元素。findFirst自测System.out.print(String.format("%d ", num)) ;}打印信息11 11 11 6 6 
十一、归约(将流组合成一个元素)

归约,将一个流数据的元素反复处理转化一个元素。reduce函数实现了归约功能。

reduce有三种方法签名

1、Optional reduce(BinaryOperator accumulator);

方法签名一,仅接收一个BinaryOperator函数式接口,对元素进行收集归纳,返回Optional对象。示例如下。

List<Integer> numbers = new ArrayList<> (Arrays.asList(1,4,3,2,6,5,8,11,9,15,10,12,7)); //创建集合
System.out.println("累加值: " + numbers.stream().reduce((a,b) -> a += b).get()); //累加
打印信息如下
累加值: 93

2、T reduce(T identity, BinaryOperator accumulator)

方法签名二、接收两个参数identity初始参数,BinaryOperator函数式接口。返回的元素类型为identity的类型。这一点需要注意。示例如下。

List<Integer> numbers = new ArrayList<> (Arrays.asList(1,4,3,2,6,5,8,11,9,15,10,12,7)); //创建集合
System.out.println("累加值: " + numbers.stream().reduce(1,(a,b) -> a += b));//累加,初始值为1。
打印信息如下
累加值: 94 (比方法签名一多了1.表示identity加入了运算之中)

方法签名三、一般在并发流的情况下才使用该签名方法。接收三个参数identity初始参数。BiFunction<U, ? super T, U> 函数式接口(输入两个参数U和T,返回一个结果U),对元素进行收集归纳。BinaryOperator函数式接口也是BiFunction的特殊体,对BiFunction处理返回的元素进行合并。返回的元素类型为identity的类型。一般情况下使用并行流才会触发执行BinaryOperator操作。示例代码如下。

		List<Integer> numbers = new ArrayList<> (Arrays.asList(1,2,3,4)); //创建集合/*******************************并行流处理 start *************************************************/int num = numbers.parallelStream().reduce(1, (a,b) -> {System.out.println(String.format("currentName=%s BiFunction a = %d ,b = %d",Thread.currentThread().getName(), a,b));return a  + b;},(a,b) -> {System.out.println(String.format("currentName=%s BinaryOperator a = %d ,b = %d",Thread.currentThread().getName(), a,b));return a + b;});System.out.println(String.format("最终结果 %d", num));/*******************************并行流处理 end *************************************************/打印信息currentName=ForkJoinPool.commonPool-worker-1 BiFunction a = 1 ,b = 2currentName=ForkJoinPool.commonPool-worker-2 BiFunction a = 1 ,b = 4currentName=main BiFunction a = 1 ,b = 3currentName=ForkJoinPool.commonPool-worker-2 BinaryOperator a = 4 ,b = 5currentName=ForkJoinPool.commonPool-worker-3 BiFunction a = 1 ,b = 1currentName=ForkJoinPool.commonPool-worker-3 BinaryOperator a = 2 ,b = 3currentName=ForkJoinPool.commonPool-worker-3 BinaryOperator a = 5 ,b = 9最终结果 14/*******************************普通流处理 start *************************************************/int num = numbers.stream().reduce(1, (a,b) -> {System.out.println(String.format("currentName=%s BiFunction a = %d ,b = %d",Thread.currentThread().getName(), a,b));return a  + b;},(a,b) -> {System.out.println(String.format("currentName=%s BinaryOperator a = %d ,b = %d",Thread.currentThread().getName(), a,b));return a + b;});System.out.println(String.format("最终结果 %d", num));/*******************************普通流处理 end *************************************************/打印信息currentName=main BiFunction a = 1 ,b = 1currentName=main BiFunction a = 2 ,b = 2currentName=main BiFunction a = 4 ,b = 3currentName=main BiFunction a = 7 ,b = 4最终结果 11

从并行流和普通流的打印信息来看。普通流直接累加处理了数据,并不调用合并器处理。并行流并行处理,最终调用合并器合并数据。而且在某些情况下,使用并发流和普通有时候流执行获取的结果并不一致。看打印的线程名称 。上面例子中普通流顺序处理数据(1 + 1 = 1 + 2 = 3 + 3= 6 + 4 =11). 并行流处理流程是初始值1 分别与流中的数据相加得到4个数据 (1 + 1=2,1+2=3,1+3=4,1+4=5),再将这四个数据合并(2+3=5+4=9+5=14)。记住,理论上对数据量较大,性能要求较高,使用并行流处理的情况下才使用方法签名三处理数据。使用该签名方法要考虑清楚流程与规范。

这一节,挑选了几个比较有代表性的操作方法做案例讲解。还有不少操作没有讲解。有时间,大家可自行研究。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OM6621F低功耗低成本蓝牙芯片支持BLE5.1和2.4G私有协议集成了电源管理单元(PMU)BMS电池管理领域首选方案

OM6621Fx是一款专为蓝牙低功耗和专有2.4GHz应用设计的功率优化的真系统级芯片(SOC)解决方案。它集成了高性能和低功率的射频收发器,具有蓝牙基带和丰富的外围I0扩展。OM6621Fx还集成了电源管理单元(PMU),以实现高效率的电源管理。它针对2.4GHz蓝牙低功耗系统、专有2.4GHz系统…

Jetpack架构组件学习(6)——使用Glance实现桌面小组件

原文地址: Jetpack架构组件学习(6)——使用Glance实现桌面小组件-Stars-One的杂货小窝公司陆续整了几个Compose写的app,有个小组件的功能,顺便试了下Jetpack库里的Glance框架 感觉与原来的Remoteview差点意思,不过点击事件的使用比Remoteview要方便不少PS: 如果想看Remoteview实…

《操作系统真象还原》第九章 线程(二) 多线程轮转调度

本文是对《操作系统真象还原》第九章(二)学习的笔记,欢迎大家一起交流第九章 线程(二) 多线程轮转调度 本文是对《操作系统真象还原》第九章(二)学习的笔记,欢迎大家一起交流,目前所有代码已托管至 fdx-xdf/MyTinyOS 。 上一节中成功创建了线程并运行,这一节要实现的…

Cisco APIC 6.0(8e)M - 应用策略基础设施控制器

Cisco APIC 6.0(8e)M - 应用策略基础设施控制器Cisco APIC 6.0(8e)M - 应用策略基础设施控制器 Application Policy Infrastructure Controller (APIC) 请访问原文链接:https://sysin.org/blog/cisco-apic-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org思科…

clickhouse本地表和分布式表说明(3分片单副本)

环境: clickhouse:24.8.11.51.创建本地表和分布式表 在一个节点上执行即可,我这里配置的分片使用了 defaultclickhouse-client --host 192.168.1.102 --port=9000 use db_test CREATE TABLE tb_test_local ON CLUSTER default (id Int32,name String,timestamp DateTime DEFAUL…

分发测试

协程的IO asyncio 作为实现异步编程的库,任务执行中遇到系统IO的时能够自动切换到其他任务。协程的IO asyncio 作为实现异步编程的库,任务执行中遇到系统IO的时能够自动切换到其他任务。协程使用的IO模型是IO多路复用。在 asyncio 低阶API 一篇中提到过 “以Linux系统为例,I…

【图】数场功能架构图

【图】数场功能架构图(来源:国家数据基础设施建设指引) (1)点:参与方之间的自身数据安全能力约定; (2)线:涉及到网络高可用,可以根据DSMM评估域进行统一约定; (3)面:DSMM中数据生存周期安全,场景化能力约定;

hyperledger

https://topgoer.cn/docs/blockchain_guide/blockchain_guide-1emut2dv80st1Hyperledger 所有项目代码托管在 Github上。目前,主要包括如下顶级项目(按时间顺序)。Fabric:包括 Fabric、Fabric CA、Fabric SDK(包括 Node.Js、Java、Python 和 Go 语言)等,目标是区块链的基…

【图】数联网功能架构图

【图】数联网功能架构图(来源:国家数据基础设施建设指引)

米尔瑞芯微第二代8nm高性能AIOT平台-RK3576开发板怎么样?

文章来源公众号:电子开发学习 瑞芯微近期推出了第二代8nm高性能AIOT平台——RK3576。 RK3576应用方向指向工业控制及网关,云终端,人脸识别设备,车载中控,商显等等。参数方面,内置了四核Cortex-A72+四核Cortex-A53,频率最高2.2GHz,内置ARM G52 MC3 GPU,NPU算力高达6TO…

openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译

openssl头文件出现DEPRECATEDIN_1_1_0导致引入头文件时程序无法编译我使用的是unbuntu20.04版本中,通过apt安装的openssl,发现openssl中的多个库文件中会出现类似DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x)),导致引入头文件时无法编译成功. 例如bio.…

人工智能创新型教师培育计划(第一期)

Skip to contentOpenHydraSearchKMain Navigation首页 课程新一代人工智能经典实验【中学】 XEdu系列【中学】 中小学AI开源课程倡议使用指南活动获取支持On this page人工智能创新型教师培育计划(第一期) 一、组织单位 二、活动背景 三、活动内容 四、活动安排 五、师资介绍…