Java8中Stream、Function、Opotions特性使用案例

所有数据都基于UserInfo类,其中包含了 userId、userName、course、score 等字段,下面是如何使用Options、 Stream 、Function来处理 UserInfo 对象列表的一些示例

List<UserInfo> userInfoList = Arrays.asList(new UserInfo(1L, "Alice", "Math", 90),new UserInfo(2L, "Bob", "Physics", 85),new UserInfo(3L, "Charlie", "Chemistry", 88),new UserInfo(4L, "Diana", "Math", 92),new UserInfo(5L, "Eve", "Physics", 89));@Data
public static class UserInfo {private Long userId;private String userName;private String course;private int score;public UserInfo(Long userId, String userName, String course, int score) {this.userId = userId;this.userName = userName;this.course = course;this.score = score;}public String getCourse() {return course;}
}

所有数据都基于UserInfo类,其中包含了 userId、userName、course、score 等字段,下面是如何使用 Java Stream API 来处理 UserInfo 对象列表的一些示例

  List<UserInfo> userInfoList = List.of(new UserInfo(1L, "Alice", "Math", 90),new UserInfo(2L, "Bob", "Physics", 85),new UserInfo(3L, "Charlie", "Chemistry", 88),new UserInfo(4L, "Diana", "Math", 92),new UserInfo(5L, "Eve", "Physics", 89));

一、Stream用法

    Stream是Java 8中引入的全新API,可以极大地方便我们对集合、数组等数据源进行连续操作

 

1.1 流的创建

通过集合 Collection.stream() 创建 Stream,一般开发中常用这种方式创建流

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Stream<String> streamFromCollection = names.stream();

通过数组 Arrays.stream 创建 Stream

String[] names = {"Alice", "Bob", "Charlie"};
Stream<String> streamFromArray = Arrays.stream(names);

通过 Stream.of() 方法创建 Stream

Stream<String> streamFromOf = Stream.of("Alice", "Bob", "Charlie");

使用 Stream.iterate() 创建无限流

 Stream<Long> infiniteStream = Stream.iterate(0L, n -> n + 2).limit(5); // 限制元素数量

⚠️注意:Stream.iterate() 方法可以用来创建无限流,但在实际使用时通常会配合limit()方法来限制流中的元素数量,以避免无限循环

1.2 流的使用

1.2.1 foreach遍历

 🌰示例 : 打印所有用户的信息

userInfoList.stream().forEach(System.out::println);

1.2.2 filter过滤

🌰示例:找出所有学数学的学生

List<UserInfo> userList = userInfoList.stream().filter(user -> "Math".equals(user.getSubject())).collect(Collectors.toList());

1.2.3 sorted排序

sorted支持两种方式:

//自然排序,元素须实现 Comparable 接口,并且 compareTo 方法将被用于确定排序顺序
Stream<T> sorted();
//自定义排序,使用 Comparator
Stream<T> sorted(Comparator<? super T> var1);

🌰示例:按照分数升序排序

List<UserInfo> userList = userInfoList.stream().sorted(Comparator.comparing(UserInfo::getScore)).collect(Collectors.toList());

1.2.5 map/flatMap映射

🌰示例 : 获取所有用户的名字userName

List<String> userNameList = userInfoList.stream().map(UserInfo::getUserName).collect(Collectors.toList());

1.2.4 distinct 去重

 🌰示例 :获取所有学科名称

List<String> courseList = userInfoList.stream().map(UserInfo::getCourse).distinct().collect(Collectors.toList());

1.2.6 reduce规约

 🌰示例 : 计算总分

int totalScore = userInfoList.stream().map(UserInfo::getScore).reduce(Integer::sum).orElse(0); //流中没有任何元素时返回默认值0//或者默认初始值为0 //.reduce(0, Integer::sum)

1.2.7 collect收集

1.2.7.1 toList/toSet/toMap归集

toList/toSet

🌰示例 :将用户收集到新的集合中

List<UserInfo> userList = userInfoList.stream().collect(Collectors.toList());Set<UserInfo> userList = userInfoList.stream().collect(Collectors.toSet());

toMap有一点特殊

🌰示例2:获取userInfoList的映射集合Map<userId,UserInfo>

Map<String, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId, userInfo -> userInfo));
Map<String, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId, Function.identity()));

 lambda 表达式 userInfo -> userInfo 作为第二个参数传递给 Collectors.toMap()。这与使用 Function.identity() 的效果相同,因为 Function.identity() 本质上就是返回一个函数,该函数接收一个参数并返回相同的参数

⚠️:可能会出现Duplicate Key

因此:

Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId,Function.identity(), (newVal,oldVal)->newVal));

🌰示例:按照userInfoList的插入顺序转为集合Map<userId,UserInfo>

Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getUserId,Function.identity(), (newVal,oldVal)->newVal),LinkedHashMap::new
);
1.2.7.2 groupingBy分组

🌰示例:将所有用户按课程分组

Map<String, List<UserInfo>> usersByCourse = userInfoList.stream().collect(Collectors.groupingBy(UserInfo::getCourse));
1.2.7.3 joining拼接

🌰示例:将所有的用户名使用“,”拼接成字符串返回

 String allName = userInfoList.stream().map(UserInfo::getName).collect(Collectors.joining(", "));
1.2.7.4 counting/summingInt/averagingInt/summarizingInt聚合

计数:counting

最值:maxBy、minBy

求和:summingInt、summingLong、summingDouble

平均值:averagingInt、averagingLong、averagingDouble

统计以上所有:summarizingInt、summarizingLong、summarizingDouble,其中包含了流中元素的计数、总和、平均值、最小值和最大值

                        

 🌰示例 : 计算总分

 使用 .collect 和 Collectors.summingInt

int totalScore = userInfoList.stream().collect(Collectors.summingInt(UserInfo::getScore));

1.2.7.4 reducing 规约

 🌰示例 : 计算总分

Integer toatlScore = userInfoList.stream().collect(Collectors.reducing(0, UserInfo::getScore, Integer::sum));
1.2.7.5  max/min/sum/count聚合

🌰示例 :获取最高分

int maxScore = userInfoList.stream().mapToInt(UserInfo::getScore).max().orElse(0);

⚠️:此处如果使用.map(UserInfo::getScore) 会错误,由于于StreamIntStream的区别,以及它们各自提供的max()方法的不同

Stream的max()需要实现Comparator来比较元素

Optional<T> max(Comparator<? super T> comparator)

而IntStream的max()

OptionalInt max();

 🌰示例 : 计算总分

reduce求和的结果是一样,但sum方法通常会更快一些,因为它直接针对IntStream进行了优化

int totalScore = userInfoList.stream().mapToInt(UserInfo::getScore).sum()
1.2.7.6 peek查看

1.2.7 limit/skip

🌰示例:按分数排序


serName

List<String> userNames = userInfoList.stream().map(UserInfo::getUserName).collect(Collectors.toList());

1.2

🌰示例:将所有用户按课程course分组

Map<String, List<UserInfo>> usersByCourse = userInfoList.stream().collect(Collectors.groupingBy(UserInfo::getCourse));

🌰示例:将所有用户的分数求和

📌方法1:使用 .map 和 .reduce

int totalScore = userInfoList.stream().map(UserInfo::getScore).reduce(0, Integer::sum);

📌方法2:使用 .collect 和 Collectors.summingInt

int totalScore = userInfoList.stream().collect(Collectors.summingInt(UserInfo::getScore));

📌方法3:使用 .mapToInt 和 .sum

int totalScore = userInfoList.stream() .mapToInt(UserInfo::getScore) .sum();

Lambda使用了函数式编程,在jdk1.8中内置了四个常用的函数式编程的接口,分别是:Function、Predicate、Supplier、Consumer。下面我们来分别介绍下这些类

java -Function、Predicate、Supplier、Consumer及自定义实现

二、Optional

不使用Optional的示例:需要手动检查列表是否为空,并处理空值情况。
使用Optional的示例:简化了代码,通过Optional自动处理空值情况

1. 创建Optional对象
Optional.of(T value):创建一个包含非空值的Optional对象。
Optional.ofNullable(T value):创建一个包含非空值的Optional对象,如果值为null则返回一个空的Optional对象

Map<Long, Map<String, Long>> meterTypeMap = Optional.ofNullable(meterTypeList)
.orElse(Collections.emptyList()).stream()
.collect(Collectors.groupingBy(DeviceMeterTypeEntity::getProjectId,         Collectors.toMap(DeviceMeterTypeEntity::getMeterSign, DeviceMeterTypeEntity::getDeviceTypeId)));

通过这些示例,我们可以看到Optional如何帮助我们安全地处理可能为空的情况,并提供默认值。这样可以避免空指针异常,使代码更加健壮。Optional的主要用法包括:
创建Optional对象:使用Optional.of或Optional.ofNullable。
检查Optional是否为空:使用isPresent或isEmpty。
获取Optional中的值:使用get或orElse。
处理Optional中的值:使用ifPresent或ifPresentOrElse。
转换Optional中的值:使用map或flatMap。

二、Function用法

在Java中,Function<T,R>接口是Java 8引入的函数式接口之一,它代表了一个将一个类型的参数映射到另一个类型的返回值的函数。下面通过UserInfo类的例子来展示Function的几种常见用法:

Function函数有三个主要的方法:apply、compose、andThen
apply:该方法意义是执行当前函数的方法体。
compose(before):先执行before函数方法体,使用其返回参数,再执行调用者函数的方法体。
andThen (after):先执行调用者方法,将其返回值作为参数调用after函数方法体

使用Function

  Function<UserInfo, Long> getUserId = UserInfo::getUserId;

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

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

相关文章

闯关leetcode——206. Reverse Linked List

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/reverse-linked-list/ 内容 Given the head of a singly linked list, reverse the list, and return the reversed list. Example 1: Input: head [1,2,3,4,5] Output: [5,4,3,2,1] Example 2:…

【23CSPJ普及组】一元二次方程(uqe)

时间限制: 1000 ms 内存限制: 524288 KB 【题目描述】 众所周知&#xff0c;对一元二次方程 &#x1d44e;&#x1d44f;&#x1d465;&#x1d450;0,(&#x1d44e;≠0)&#xff0c;可以用以下方式求实数解&#xff1a; ∙∙ 计算 Δ−4ac&#xff0c;则: 1. 若 Δ&…

【功能介绍】在信创终端上查看系统的硬盘序列号以及USB设备的VID和PID _ 统信 _ 麒麟 _ 方德

往期好文&#xff1a;【系统配置】命令行修改统信UOS的grub启动延时 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于如何在信创终端上查看系统的硬盘序列号以及USB设备的VID和PID的文章。在日常使用中&#xff0c;查看硬盘的序列号以及USB设备的VID&#xff08;…

电脑篇——Windows设置文件夹只读功能(高级篇)

使用背景&#xff1a; 某工厂产线上的Windows电脑里面有一些生产测试软件在指定的文件夹中&#xff08;下文中称为文件夹A&#xff09;。为了防止普通职工随意修改、删除、替换文件&#xff0c;对生产软件版本管控产生不可控因素&#xff0c;我们需要给文件夹A添加保护&#xf…

基于RabbitMQ,Redis,Redisson,RocketMQ四种技术实现订单延时关闭功能及其相关优缺点介绍(以12306为主题)

目录 1. 延迟关闭订单 1.1 订单延时关闭功能技术选型 1.1.1 定时任务 1.1.2 RabbitMQ 1.1.3 Redis 过期监听 1.1.4 Redisson 1.1.5 RocketMQ 1.2 RocketMQ订单延时关闭发送方实现 1.3 RocketMQ订单延时关闭的消费方实现 1. 延迟关闭订单 用户发起订单后&#xff0c;如…

2023 ICPC 亚洲澳门赛区赛 D. Graph of Maximum Degree 3

题目 题解 #include <bits/stdc.h> using namespace std; // #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 #define ll long long #define pii pair<int, int> #defi…

Spring--4

SpringWeb 概念 是Spring框架的一个模块&#xff0c;基于Servlet的一个原始Web框架。 SpringWEB 运行流程 描述&#xff1a;前端用户请求发送的后端以后&#xff0c;先经过前端控制器DispatcherServlet(再次之前也可能有过滤器的存在)&#xff0c;经过前端控制器解析后&…

一起搭WPF架构之LiveCharts.Wpf的简单了解与安装

一起搭WPF架构之LiveCharts.Wpf的简单了解与安装 前言LiveCharts.Wpf介绍LiveCharts.Wpf的安装总结 前言 根据项目需求&#xff0c;我单独留了一个界面用于进行数据分析。数据分析的内容考虑是采用图表的形式将SQLite数据库中存储的数据进行绘制成图&#xff0c;以便数据分析。…

第三十一篇:TCP协议如何解决丢包的问题,TCP系列六

前面我们说TCP协议是可靠的、基于字节流、面向连接的传输层通信协议&#xff1b; 这里我想换种说法&#xff1a;与其说是TCP协议是可靠的&#xff0c;不如说传输层程序软件实现了TCP协议的规范&#xff08;网络层次模型&#xff0c;每一层都有对应的程序软件&#xff09;&…

33 类与对象 · 下

目录 一、构造函数的深入 &#xff08;一&#xff09;构造函数的其他特点 &#xff08;二&#xff09;使用例 1、Date类与Time类显示写 2、Date类与Time类写一部分 &#xff08;三&#xff09;总结 &#xff08;四&#xff09;初始化顺序小题目 二、类型转化 &#xff…

【芯片设计】DC综合retiming策略的学习与实践

对于DC综合中的retiming策略早有耳闻&#xff0c;但是一直没有比较系统的学习和实验过&#xff0c;正好借着这次交付过程的归纳总结机会&#xff0c;把一些零零散散的收获学习记录下。 记得刚出新手村时和某位大佬聊到过&#xff0c;他说你逻辑里写了在某级计算一个结果&#…

UE5之5.4 第一人称示例代码阅读2 子弹发射逻辑

TP_WeaponComponent.h 看看头文件 暴露了attach weapon和fire给蓝图 这两个函数意义一看名字吧&#xff0c;就是捡起来枪的时候执行&#xff0c;一个就是发射子弹的时候执行 #pragma once#include "CoreMinimal.h" #include "Components/SkeletalMeshComponen…

Appium中的api(二)

目录 元素定位操作api 1--通过id定位api 2--通过class获取定位元素 3--通过xpath表达式定位元素 4.完整代码 解释 效果 元素定位操作api 1--通过id定位api 注:driver.find_element是获取单个元素 # 通过id获取 mySearchId "com.android.settings:id/search_acti…

如何对pdf文件进行加密?pdf文件加密全攻略与深度解析(5个方法)

如何对pdf文件进行加密&#xff1f; 只见&#xff0c;在深夜的情报局里&#xff0c;特工小李将一份绝密PDF文件放在保险箱内&#xff0c;以为这样就天衣无缝了。 细细推敲&#xff0c;漏洞百出&#xff1a; 如果钥匙被盗呢&#xff1f;如果被神匠破解出密码呢&#xff1f;如果…

Halcon基础-瓶盖带角度的OCR批量识别

Halcon基础-OCR识别 1、OCR识别素材2、创建路径文件3、Halcon代码实现4、运行效果5、资源获取 1、OCR识别素材 这里我准备了7张不同角度的OCR图片&#xff0c;如下所示&#xff1a; 2、创建路径文件 按照下图所示创建全部文件夹和文件&#xff1a; 01用来存放OCR识别原图 c…

Vue中使用el-upload实现文件上传时控制提交按钮状态的最佳实践

在Web应用开发中&#xff0c;文件上传是一个常见的需求。在使用Vue框架和Element UI库时&#xff0c;我们经常使用el-upload组件来处理文件上传。但是&#xff0c;如何在上传过程中控制提交按钮的可用状态&#xff0c;以避免在上传未完成时误触提交操作&#xff0c;是一个值得探…

解决:如何在opencv中得到与matlab立体标定一样的矫正图?(python版opencv)

目的&#xff1a;采用一样的标定参数&#xff0c;matlab中和opencv中的立体矫正图像是一样的吗&#xff1f;不一样的话怎么让它们一样&#xff1f; 结论&#xff1a;不一样。后文为解决方案。 原因&#xff1a;注意matlab的标定结果在matlab中的用法和在opencv中的用法不一样&a…

光伏电站折旧率的计算

折旧率的计算方法 直线法&#xff1a;直线法是最常用的折旧计算方法。它假设光伏设备在使用寿命内每年的折旧额保持不变。计算公式为&#xff1a; 折旧率(资产原值-净残值)预计使用寿命。 其中&#xff0c;资产原值是指光伏设备购置价值或建成投产时的价值&#xff1b;净残值…

chrome清除https状态

莫名其妙的http跳转到https的url了。 解决办法 浏览器地址栏输入&#xff1a;chrome://net-internals/#hsts 输入你需要删除的域名即可&#xff01;&#xff01;&#xff01;