Java中Stream的应用

news/2024/5/14 16:22:41/文章来源:https://blog.csdn.net/twi_twi/article/details/130020493

Stream简介

Java 8 版本新增的Stream,配合同版本出现的Lambda ,给我们操作集合(Collection)提供了极大的便利。

Stream可以由数组或集合创建,对流的操作分为两种:

  • 中间操作:每次返回一个新的流,可以有多个。
  • 终端操作:每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

image-20230407132236526

创建Stream

  1. 通过 java.util.Collection.stream() 方法用集合创建流

    List<String> list = Arrays.asList("a", "b", "c");
    // 创建一个顺序流
    Stream<String> stream = list.stream();
    // 创建一个并行流
    Stream<String> parallelStream = list.parallelStream();
    
  2. 使用 java.util.Arrays.stream(T[]array)方法用数组创建流

    int[] array={1,3,5,6,8};
    IntStream stream = Arrays.stream(array);
    
  3. 使用 Stream 的静态方法:of()、iterate()、generate()

    Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
    stream2.forEach(System.out::println);Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
    stream3.forEach(System.out::println);
    

stream和 parallelStream的简单区分:

  • stream是顺序流,由主线程按顺序对流执行操作
  • parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。

Stream API

1、遍历/匹配(foreach/find/match)

List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);// 1.foreach
// 遍历输出符合条件的元素
list.stream().forEach(System.out::println);// 2.find
// 匹配第一个
Optional<Integer> findFirst = list.stream().findFirst();
// 匹配任意(适用于并行流)
Optional<Integer> findAny = list.parallelStream().findAny();
// findFirst.get();
// findAny.get()// 3.match
// 是否包含符合特定条件的元素
boolean anyMatch = list.stream().anyMatch(x -> x < 6);

2、按条件匹配filter

// 筛选员工中已满18周岁的人,并形成新的集合
List<Person> collect = personList.stream().filter(x -> x.getAge()>=18).collect(Collectors.toList());

3、聚合max、min、count

// 获取String集合中最长的元素
List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu");
Optional<String> max = list.stream().max(comparator);
System.out.println(max);
// Optional[zhangsan]
List<Integer> list = Arrays.asList(1, 17, 27, 7);
Optional<Integer> max = list.stream().max(Integer::compareTo);
// 自定义排序
Optional<Integer> max2 = list.stream().max(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o1.compareTo(o2);}
});
System.out.println(max2);
// Optional[27]

4、map与flatMap

  • map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
// 整数数组每个元素+3
List<Integer> list = Arrays.asList(1, 17, 27, 7);
List<Integer> collect = list.stream().map(x -> x + 3).collect(Collectors.toList());
System.out.println(collect);
// [4, 20, 30, 10]
// 将两个字符数组合并成一个新的字符数组
String[] arr = {"z, h, a, n, g", "s, a, n"};
List<String> list = Arrays.asList(arr);
System.out.println(list);
List<String> collect = list.stream().flatMap(x -> {String[] array = x.split(",");Stream<String> stream = Arrays.stream(array);return stream;
}).collect(Collectors.toList());
System.out.println(collect);
// [z, h, a, n, g, s, a, n]

5、规约reduce

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

// 求Integer集合的元素之和、乘积和最大值
List<Integer> list = Arrays.asList(1, 2, 3, 4);
//求和
Optional<Integer> reduce = list.stream().reduce((x,y) -> x+ y);
System.out.println("求和:"+reduce);
//求积
Optional<Integer> reduce2 = list.stream().reduce((x,y) -> x * y);
System.out.println("求积:"+reduce2);
//求最大值
Optional<Integer> reduce3 = list.stream().reduce((x,y) -> x>y?x:y);
System.out.println("求最大值:"+reduce3);
Optional<Integer> reduce = personList.stream().map(Person :: getSalary).reduce(Integer::sum);
Optional<Integer> reduce2 = personList.stream().map(Person :: getSalary).reduce(Integer::max);
System.out.println("工资之和:"+reduce);
System.out.println("最高工资:"+reduce2

6、collect

Collectors中用于数据统计的静态方法
  • 计数: count
  • 平均值: averagingInt、 averagingLong、 averagingDouble
  • 最值: maxBy、 minBy
  • 求和: summingInt、 summingLong、 summingDouble
  • 统计以上所有: summarizingInt、 summarizingLong、 summarizingDouble
//Collectors.counting():统计员工人数
Long count = personList.stream().collect(Collectors.counting());//Collectors.averagingDouble(Person::getSalary):求平均工资
Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));//Collectors.maxBy(Integer::compare):求最高工资
Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));//Collectors.summingInt(Person::getSalary):求工资之和
Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));//Collectors.summarizingDouble(Person::getSalary):一次性统计所有信息DoubleSummaryStatistics
DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
收集(toList、toSet、toMap)
//collect(Collectors.toList());
//collect(Collectors.toSet());// toMap
Map<String, Person> collect = personList.stream().filter(x -> x.getAge() > 18).collect(Collectors.toMap(Person::getName, y -> y));
System.out.println(collect);
分组(partitioningBy/groupingBy)
  • 分区:将stream按条件分为两个 Map,比如员工按薪资是否高于8000分为两部分。
  • 分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
// Collectors.partitioningBy(x -> x.getSalary() > 8000):将员工按薪资是否高于8000分组
Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));// Collectors.groupingBy(Person::getSex):将员工按性别分组
Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));// Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)):将员工先按性别分组,再按地区分组
Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
连接joining

joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。

String names = personList.stream().map(x->x.getName()),collect(Collectors.joining(","))

7、排序sorted

// .sorted(Comparator.comparing(Person::getSalary)):按工资升序排序(自然排序)
List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName).collect(Collectors.toList());// .sorted(Comparator.comparing(Person::getSalary).reversed():按工资倒序排序
List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).map(Person::getName).collect(Collectors.toList());// .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)):先按工资再按年龄升序排序
List<String> newList3 = personList.stream().sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName).collect(Collectors.toList());// 先按工资再按年龄自定义排序(降序)
List<String> newList4 = personList.stream().sorted((p1, p2) -> {if (p1.getSalary() == p2.getSalary()) {return p2.getAge() - p1.getAge();} else {return p2.getSalary() - p1.getSalary();}
}).map(Person::getName).collect(Collectors.toList());

8、提取/组合

合并、去重、限制、跳过等操作。

tring[] arr1 = { "a", "b", "c", "d" };
String[] arr2 = { "d", "e", "f", "g" };
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);// concat:合并两个流 distinct:去重
List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());// limit:限制从流中获得前n个数据
List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());// skip:跳过前n个数据
List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());

List());

// limit:限制从流中获得前n个数据
List collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());

// skip:跳过前n个数据
List collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());


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

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

相关文章

DALL·E:OpenAI第一代文本生成图片模型

1 简介 本文根据openAI 2021年2月的《Zero-Shot Text-to-Image Generation》翻译总结的。原文详见https://arxiv.org/pdf/2102.12092v1.pdf。 DALLE : 论文中没看到这个名字&#xff0c;可能是后起的吧。 DALLE有120亿参数&#xff0c;基于自回归transformer&#xff0c;在2…

Spring 01 -项目管理框架Spring入门

本部分理解原理就好 Spring入门1 Spring引入1.1 原生web开发中存在的问题2 Spring2.1 Spring的概念2.2 Spring 作用2.3 Spring的组成2.4 spring的IOC底层实现原理3 Spring快速入门3.1 引入spring依赖3.2 spring的配置文件3.3 测试四、Spring的开发细节4.1 BeanFactory的类间关系…

android的system_server进程的启动

android的system_server进程的启动 android的system_server进程的启动的简单介绍 system_server是Zygote的fork的第一个Java进程相当于它的大儿子&#xff0c;这个进程非常重要的&#xff0c;这里这个进程提供了很多系统线程&#xff0c;提供了所有的核心的系统服务。比如&am…

mysql与redis区别

一、.redis和mysql的区别总结 &#xff08;1&#xff09;类型上 从类型上来说&#xff0c;mysql是关系型数据库&#xff0c;redis是缓存数据库 &#xff08;2&#xff09;作用上 mysql用于持久化的存储数据到硬盘&#xff0c;功能强大&#xff0c;但是速度较慢 redis用于存储使…

SQL基础查选和条件查选

写完毕业论文&#xff0c;终于有空复习sql了&#xff0c;继续学习之旅~下次不能和上次一样&#xff0c;简单的sql语句都忘记了。 1.查询结果去重 关键字 distinct select distinct university from user_profile; 2. 将查询后的列重新命名 关键字 as 关键字limit…

Linux kernel 编译 exfat.ko ntfs.ko 来支持exFat 和 NTFS 分区

项目需求想让设备支持 exFat 和 NTFS 的文件格式. 默认的内核是不支持的,因为内核要限定1.5M之内, 所以很多东西都裁剪掉了. 而且不是所有项目都有这个需求,所以就需要编译为 ko ,按需加载; 而不是才去built-in的方式. 在如下的选项找到对应的配置. 至于如何找到, 我推荐2种方式…

LE AUDIO快速了解

有BIS和CIS两种 BIS是广播的&#xff0c;不需要连接&#xff0c;只需要监听 CIS要建立连接的&#xff0c;除了ACL链路&#xff0c;还需要建立CIS链路 BIS部分 也没啥要看的&#xff0c;只需要记住3个指令就可以了 主要是HCI的3个指令 2068 206b 206e 这3个指令即可 206…

Nacos安全性探究

Nacos怎么做安全校验的&#xff1f; 以下使用nacos2.x 如上图所示&#xff0c; 可以直接访问Nacos的接口来获取用户列表。这说明Nacos的接口被爆露&#xff0c;任何情况下都可以访问&#xff0c;因此安全性得不到保障。 Nacos 使用 spring security 作为安全框架。spring sec…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK获取每张图像的微秒时间和FrameID(C#)

BGAPI SDK获取图像微秒级时间和FrameID Baumer工业相机Baumer工业相机FrameID技术背景一、FrameID是什么&#xff1f;二、使用BGAPI SDK获取图像微秒时间和FrameID步骤 1.获取SDK图像微秒级时间2.获取SDK图像FrameIDBaumer工业相机使用微秒级时间和FrameID保存的用处Baumer工业…

混淆矩阵Confusion Matrix(resnet34 基于 CIFAR10)

目录 1. Confusion Matrix 2. 其他的性能指标 3. example 4. 代码实现混淆矩阵 5. 测试&#xff0c;计算混淆矩阵 6. show 7. 代码 1. Confusion Matrix 混淆矩阵可以将真实标签和预测标签的结果以矩阵的形式表示出来&#xff0c;相比于之前计算的正确率acc更加的直观…

jenkins打包发布前端项目

1.配置前端nodejs打包环境 1.1安装nodejs插件 1.2配置jenkins nodejs环境 2.下载git插件(使用此插件配置通过gitlab标签拉取项目) 3.创建一个自由风格的发布项目 4.配置项目构建流程 4.1添加钉钉告警 4.2配置参数化构建 4.3配置源码管理为git拉取项目 4.4配置构建环境 4.5配置…

transform属性

CSS transform属性允许对某一个元素进行某些形变, 包括旋转&#xff0c;缩放&#xff0c;倾斜或平移等。 注意事项&#xff0c;并非所有的盒子都可以进行transform的转换,transform对于行内级非替换元素是无效的,比如对span、a元素等 常见的函数transform function有&#xf…

算法笔记:匈牙利算法

1 二部图&#xff08;二分图&#xff09; 二分图&#xff08;Bipartite graph&#xff09;是一类特殊的图&#xff0c;它可以被划分为两个部分&#xff0c;每个部分内的点互不相连。 匈牙利算法主要用来解决两个问题&#xff1a;求二分图的最大匹配数和最小点覆盖数。 2 最大匹…

[C++笔记]初步了解STL,string,迭代器

STL简介 STL(standard template libaray-标准模板库)&#xff1a; 是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包含数据结构与算法的软件框架。 是一套功能强大的 C 模板类&#xff0c;提供了通用的模板类和函数&#xff0c;这些模板…

STM32开发(十二)STM32F103 功能应用 —— NTC 温度采集

文章目录一、基础知识点二、开发环境三、STM32CubeMX相关配置四、Vscode代码讲解&#xff08;过程中相关问题点在第五点中做解释说明&#xff09;五、知识点补充六、结果演示一、基础知识点 了解STM32 片内资源ADC。本实验是基于STM32F103开发 实现 NTC温度采集。 NTC温度采集…

3年外包离奇被裁,痛定思痛24K上岸字节跳动....

三年前&#xff0c;我刚刚从大学毕业&#xff0c;来到了一家外包公司工作。这份工作对于我来说是个好的起点&#xff0c;因为它让我接触到了真正的企业项目和实际的开发流程。但是&#xff0c;随着时间的流逝&#xff0c;我发现这份工作并没有给我带来足够的成长和挑战。 三年…

文心一言平替版ChatGLM本地部署(无需账号)!

今天用了一个超级好用的Chatgpt模型——ChatGLM&#xff0c;可以很方便的本地部署&#xff0c;而且效果嘎嘎好&#xff0c;经测试&#xff0c;效果基本可以平替内测版的文心一言。 目录 一、什么是ChatGLM&#xff1f; 二、本地部署 2.1 模型下载 2.2 模型部署 2.3 模型运…

数据结构系列13——排序(归并排序)

目录 1. 递归实现归并排序 1.1 思路 1.2 代码实现 1.3 时间复杂度和空间复杂度 2. 非递归实现归并排序 2.1 思路 2.2 代码实现 2.3 时间复杂度和空间复杂度 1. 递归实现归并排序 1.1 思路 将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列…

Excel 文件 - 比如 .csv文件编码问题 转为 UTF-8 编码 方法,解决中文乱码问题 - 解决科学计数显示问题

解决 excel 文件编码问题 1、方法一&#xff1a; 有点点击 excel 文件&#xff0c;然后选择打开方式&#xff0c;选择使用 Excel 2016 软件打开 选择 工具 ——> Web 选项 这里选择 UTF-8 编码 2、方法二 wps 导出为 .csv 文件&#xff0c;然后修改 csv 文件的后缀…

Linux修改密码报错Authentication token manipulation error的终极解决方法

文章目录报错说明解决思路流程排查特殊权限有没有上锁查看根目录和关闭selinux/etc/pam.d/passwd文件/etc/pam.d/system-auth文件终极办法&#xff0c;手动定义密码passwd: Have exhausted maximum number of retries for servic、ssh用普通用户登录输入密码正确但是登录时却提…