java8 stream, map, Option 等函数式编程的使用例子

Java函数式实现替代策略模式解决 if...else代码,Map+函数式接口方法 之前记录过用自定义注解和策略模式实现发不同消息的功能笔记: 文章地址:发送不同类型的消息----------策略模式_不受天磨非好汉,不遭人妒是庸才——着实着迷゛-优快云博客r一:首先看下代码结构annotation:注解context:调度容器(会存放不同消息策略实现列表)enums:不同消息类型的枚举listener:springboot项目初始化的时候初始化消息策略实现与枚举类型的绑定关系并加入到调度容器里面service:消息接口定义impl:具体消息策略实现二:具体代码讲解1:消息类型枚举:M 阅读详情

java8 stream, map 等函数式编程的一些典型用法例子如下。

例子1: 数组元素字母小写变大写。

List<String> list= Arrays.asList("a", "b", "c", "d");
List<String> collect =list.stream().map(String::toUpperCase).collect(Collectors.toList());
System.out.println(collect); //[A, B, C, D]

例子2:数组所有元素,按某种规律计算。

List<Integer> num = Arrays.asList(1,2,3,4,5);
List<Integer> collect1 = num.stream().map(n -> n * 2).collect(Collectors.toList());
System.out.println(collect1); //[2, 4, 6, 8, 10]

例子3 对数组元素的单个元素进行处理

public static String stepCondition(List<OffsetStep> step, ExtStatementRecord singleIncomeRecord) {
		String[] array = step.stream().map(item -> item.getRule().condition(item, singleIncomeRecord)).toArray(String[]::new);
		return StringUtils.join(array, " AND ");
	}

例子4:
改造for循环。

List<String> idcards=new ArrayList<String>();//
for(int i=0;i<users.size();i++){
  idcards.add(users.get(i).getName());
}
//这种方法要写好几行代码,有没有简单点的,有,java8 API能一行搞
//定:
List<String> idcards= users.stream().map(User::getIdcard).collect(Collectors.toList())

例子5:一个java 综合例子来使用Stream, collection, Optional的例子。

private void example(int coupleID, List<Map<String, Object>> masterRecordList, List<Map<String, Object>> slaveRecordsList, List<Long> masterMarksOkIds, List<Long> slaveMarksOkIds, FieldsMergeCondition mergeCondition) {
        Set<String> fieldName = getFieldName(coupleID);
        Map<String, List<Map<String, Object>>> slaveGroup = slaveRecordsList.stream().collect(Collectors.groupingBy(item -> {
            StringBuilder key = new StringBuilder();
            fieldName.forEach(column -> key.append(Optional.ofNullable(item.get(column)).orElseGet(()->"").toString().trim()));
            return key.toString();
        }));

        Set<String> rightFieldName = getRightFieldName(coupleID);
        Map<String, Map<Object, Object>> additionalMapping = verificationCommon.getAdditionalMapping(coupleID);
        for (Map<String, Object> masterRecord : masterRecordList) {
            setFieldValues(verificationCommon.getParsedCondition(coupleID), masterRecord);
            ConditionLinkNode parsedCondition = verificationCommon.getParsedCondition(coupleID);
            Map<String, Object> mappingCondition = setMappingValues(additionalMapping, masterRecord);
            StringBuilder key = new StringBuilder();
            rightFieldName.forEach(column -> key.append(Optional.ofNullable(masterRecord.get(column)).orElseGet(()->"").toString().trim()));
            List<Map<String, Object>> slaveList = slaveGroup.get(key.toString());
            if (CollectionUtils.isEmpty(slaveList)) {
                continue;
            }
            boolean verifyOk = false;
            if (Objects.isNull(mergeCondition)) {
                if (slaveList.size() > 1) {
                    List<Long> diffIds = slaveList.stream().map(this::getRecordId).collect(Collectors.toList());
                    slaveMarksOkIds.addAll(diffIds);
                    continue;
                }
                verifyOk = true;
            } else {
                verifyOk = merge(mergeCondition, masterRecord, slaveList, verifyOk);
            }
            if (verifyOk) {
                Map<String, Object> slaveRecord = slaveList.get(0);
                if (verifyData(parsedCondition, mappingCondition, slaveRecord)) {
                    slaveMarksOkIds.addAll(slaveList.stream().map(this::getRecordId).collect(Collectors.toList()));
                    Long masterId = getRecordId(masterRecord);
                    masterMarksOkIds.add(masterId);
                }
            }
        }
    }

下面是Optional的orElse和orElseGet的区别

 private static String getRandomName(String[] names) {
        System.out.println("Generating a name...");
        return "new name";
    }
 String[] names = new String[]{"zhang", "wang", "li", "zhao", "wu"};
        Optional.of("wang").orElse(getRandomName(names)); // 执行该句时会打印"Generating a name..."
        Optional.ofNullable("wang").orElse(getRandomName(names));// 执行该句时会打印"Generating a name..."
        Optional.of("wang").orElseGet(() -> getRandomName(names)); //不执行getRandomName()

注:上面Optional.of和Optional.ofNullable()返回的结果是"wang",虽然orElse()方法会执行(实际测试过)。

optional为空时:
orElse 会执行,返回orElse中的结果
orElseGet 会执行,返回orElseGet中的结果
optional有值时:
orElse 会执行,返回optional的结果
orElseGet 不会执行,返回optional的结果
结论
无论optional是否有值,orElse都会被执行。
只有optional为空时,orElseGet才会被执行。

注意,敲黑板了:
有个场景要注意。就是通过optional来操作数据库,如果查询到有数据,则update,没数据则执行insert
代码可能是这样

Optional.ofNullable(selectEntity(id)).map(update(entity)).orElse(insert(entity))

这时,如果方法上再有事物注解@transactional,那么很有可能会引起Mysql事物锁等待超时 Lock wait timeout exceeded; try restarting transaction
原因是:在同一事务内先后对同一条数据进行插入和更新操作。因为orElse是必会执行的
所以orElse中,有具体方法操作时,一定要记得使用orElseGet

另外,关于对stream() 的理解

java8中 stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
为函数式编程而生。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。
惰式执行。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
可消费性。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。

例子:Java8 用stream进行分组

     List<Map<String, Object>> slaveRecordsList=new ArrayLisy<>();
     //给slaveRecordsList赋值,省略....
     
      Set<String> fieldName = getFieldName(coupleID); //得到String Set
        Map<String, List<Map<String, Object>>> slaveGroup = slaveRecordsList.stream().collect(Collectors.groupingBy(item -> {
            StringBuilder key = new StringBuilder();
            fieldName.forEach(column -> key.append(Optional.ofNullable(item.get(column)).orElse("").toString().trim()));
            return key.toString();
        }));

List的stream的分组功能

public static void testStreamGroup(){
  List<Student> stuList = new ArrayList<Student>();
  Student stu1 = new Student("10001", "孙权", "1000101", 16, '男');
  Student stu2 = new Student("10001", "曹操", "1000102", 16, '男');
  Student stu3 = new Student("10002", "刘备", "1000201", 16, '男');
  Student stu4 = new Student("10002", "大乔", "1000202", 16, '女');
  Student stu5 = new Student("10002", "小乔", "1000203", 16, '女');
  Student stu6 = new Student("10003", "诸葛亮", "1000301", 16, '男');
 
  stuList.add(stu1);
  stuList.add(stu2);
  stuList.add(stu3);
  stuList.add(stu4);
  stuList.add(stu5);
  stuList.add(stu6);
 
  Map<String, List<Student>> collect = stuList.stream().collect(Collectors.groupingBy(Student::getClassId));
  for(Map.Entry<String, List<Student>> stuMap:collect.entrySet()){
     String classId = stuMap.getKey();
     List<Student> studentList = stuMap.getValue();
     System.out.println("classId:"+classId+",studentList:"+studentList.toString());
  }
}

参考文档

  1. java8 optional那些事
  2. java8新特性 lambda Stream map(函数式编程)
  3. Java8新特性之stream、map和reduce
  4. java通过Stream对list集合分组
    (场景:
    有一个List,想对该集合中的数据进行分组处理,则可以用java8中的stream),例子见这里。
    5.Java stream 多情况分组
  5. Java8中使用stream进行分组统计和普通实现的分组统计的性能对比
    (性能最好是:普通分组,其次是并行流分组,最差是串行流分组)
    6.Java8新特性之stream、map和reduce
Java Stream流最详细教程(含各种使用案例) 学习Stream流需要对Lambda,方法引用,Optional先了解清楚,,再去学习流会好 阅读详情

相关推荐

OpenVins解析:基于滤波框架的SLAM

这一方式存在的关键问题是匹配耗时很长,对性能影响显著。可以参考ORBSLAM3中的匹配方式来对其优化,比如左右目匹配可以在极线上搜索,前后帧可以利用运动先验投影匹配。理论上加入路标点会提升精度,代价是增加了计算量。着重说下基于描述子的匹配:OpenVins中匹配的方式是robust_match(),里面是调用的opencv的。openvins中不仅仅进行了传统的MSCKF更新(状态向量中不包含路标点),还在。中进行了包含路标点的估计更新。图像帧到来时,利用IMU递推得到的位姿给该图像帧赋初值。

qq_18076309的博客 4073

记录 java实现Map + 函数式编程封装代码

记录 一下JAVA实现Map + 函数式编程封装代码的使用,可以有效解决多if-else的使用。

lzfaq的博客 680

上下文理解的AI增强方案:AI应用架构师的架构洞察

本文将从AI应用架构师的视角,深入探讨“上下文理解”的技术本质、核心挑战,以及一套可落地的上下文增强架构方案。我们会拆解上下文理解的底层需求,分析架构设计中的关键决策,并通过具体案例展示如何构建一个能“记住过去、理解现在、预测未来”的AI系统。三个维度:上下文的内容范围(短期/中期/长期)、数据类型(文本/结构化/多模态)、技术挑战(窗口限制/信息过载/跨会话一致性);三种架构模式:分层上下文存储(热/冷数据分离)、上下文路由(按需筛选)、动态压缩(适配模型窗口);四个关键组件。

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 219

java函数式编程 map_函数式编程-对Java 8流进行分区

将任意源流划分为固定大小的批次是不可能的,因为这会加重并行处理。 并行处理时,您可能不知道拆分后第一个子任务中有多少个元素,因此您无法为下一个子任务创建分区,直到完全处理第一个子任务。但是,可以从随机访问ofSubLists创建分区流。例如,在我的ofSubLists库中可以使用这种功能:List input = Arrays.asList(...);Stream> stream = Str...

weixin_31176383的博客 277

信息学奥赛一本通高手训练1680:序列

题目 代码 #include<cstdio> #include<iostream> #include<cmath> #define LL long long using namespace std; const LL N = 1400000+7; const LL mod = 1e9+7; int n, t; LL pos[N], sum[N], ans[N]; struct node{ LL ll, rr; }a[N]; int main(){ p

qingfeixueyue的博客 468

java函数式编程 map_Java8函数式编程:3.10进阶练习:map和filter实现

只用reduce 和Lambda 表达式写出实现Stream 上的map 操作的代码,如果不想返回Stream,可以返回一个List。// reduce实现mapprivate Stream map(Stream stream, Function fun) {return stream.reduce(new ArrayList().stream(), // Stream是reduce参数的的U...

weixin_35890512的博客 479

FortiOS 存在身份验证绕过导致命令执行漏洞(CVE-2024-55591)

FortiOS 是 Fortinet 公司开发的操作系统,作为 Fortinet 安全平台的核心,提供全面的网络安全功能。 它将网络和安全功能无缝集成,支持跨本地、云、混合和融合 IT/OT/IoT 基础设施环境的统一管理。 FortiOS 7.6 版本引入了生成式人工智能助手、数据保护、托管服务和单一代理等新功能,进一步增强了其安全性和性能。

缘梦未来的博客 1841

JAVA8 Optional新特性和使用详解

文章目录一、Optional简介二、应用Optional1、创建Optional对象2、Optional中map用法3、Optional其它方法用法三、Optional实战1、创建Optional实例2、默认值 前言:在介绍Optional之前我们先回顾Stream流中两个方法map和flatMap区别。 map只是一维 1对1 的映射 而flatmap可以将一个2维的集合映射成一个一维,相当于他映射的深度比map深了一层。说的专业点就是,各个流会被合并或者扁平化为一个单一的流。 例: public sta

境里婆娑 4333

34、Text2KGBench与GeoQuestions1089:知识图谱生成与地理空间问答的新进展

本文介绍了Text2KGBench和GeoQuestions1089在知识图谱生成与地理空间问答领域的最新进展。Text2KGBench提供了一个开放且可复现的基准,用于从文本生成知识图谱,并结合多个LLM模型和评估工具推动研究。GeoQuestions1089是目前最大的地理空间问答数据集,与GeoQA2系统结合,推动了地理空间问答系统的发展。文章还探讨了技术挑战和未来研究方向,包括多模态知识图谱生成和深度学习优化的地理空间问答系统。

css33的专栏 114

【AI面试】 Python 的装饰器

Python装饰器是一种高阶函数,用于在不修改原函数代码的情况下增强其功能。它通过@语法糖接收目标函数作为参数,并返回一个包含额外逻辑(如日志、缓存、权限验证等)的新函数。装饰器的核心价值在于代码复用和解耦,符合开闭原则,典型应用包括性能分析、权限控制等场景。例如,@timer_decorator可自动为函数添加耗时统计功能。本质上,@decorator等价于func = decorator(func),实际调用的是装饰器返回的包装函数。进阶技巧包括使用@functools.wraps保留原函数元信息。装饰

钱多多先森 183

Java8 lambda表达式详解

Scala中函数是一等公民,有大量的函数式编程,而Java1.8的新特性也加入了函数式编程,转载如下。 关键词:函数式接口、lambda表达式 作用:函数式编程、替换匿名内部类(利用lambda实现函数式中的函数)。 基本语法:3 部分 1 左侧:一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数 2 中间:一个箭头符号:-> 3 右侧:方法体,可以是表达式和代码块...

统木木的博客 1万+

Raspberry Pi 4 ARM Trusted Firmware 技术解析

摘要: 本文详细介绍了在树莓派4(Raspberry Pi 4)上移植ARM可信固件(TF-A)的实现方案与安全考量。该移植专注于BL31功能,作为非安全世界(如Linux内核)的启动桥梁,支持加载EL2级别程序。文章分析了启动流程、内存映射设计,并对比了RPi3与RPi4的关键差异,指出当前版本缺乏硬件级安全内存保护的局限性。此外,提供了构建指南、配置说明及设备树自动修补的实现细节,强调通过config.txt简单配置即可启动64位内核。该方案充分利用树莓派原有GPU固件流程,兼顾兼容性与简易性。

Linux内核架构师 932

深入显出Java函数式编程

java8新特性——Lambda表达式、Optional、Stream流等操作介绍和使用。

这里是Mae。 1333

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

java 使用_使用 Vavr 进行函数式编程

在本系列的 上一篇 文章中对 Java 平台提供的 Lambda 表达式和流做了介绍。受限于 Java 标准库的通用性要求和二进制文件大小,Java 标准库对函数式编程的 API 支持相对比较有限。函数的声明只提供了 Function 和 BiFunction 两种,流上所支持的操作的数量也较少。为了更好地进行函数式编程,我们需要第三方库的支持。Vavr 是 Java 平台上函数式编程库中的佼佼者...

weixin_30477489的博客 466

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Java的Stream流和Option类

Stream提供了更简洁、声明式的方式处理数据流。中间操作如filter()map()flatMap()等支持链式操作,实现强大的数据处理能力。终止操作则触发最终的处理过程,如collect()forEach()reduce()等。

Dong雨的博客 1188

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

《Java8实战》笔记(15):面向对象和函数式编程的混合-Java 8和Scala的比较

JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!以扫码获取!!(备注Java获取)**

2401_83916283的博客 422

java map获取第一个值_深入理解 Java 函数式编程(4): 使用 Vavr 进行函数式编程...

在本系列的上一篇文章中对 Java 平台提供的 Lambda 表达式和流做了介绍。受限于 Java 标准库的通用性要求和二进制文件大小,Java 标准库对函数式编程的 API 支持相对比较有限。函数的声明只提供了 Function 和 BiFunction 两种,流上所支持的操作的数量也较少。为了更好地进行函数式编程,我们需要第三方库的支持。Vavr 是 Java 平台上函数式编程库中的佼佼者。V...

weixin_40005373的博客 444

JDK1.8 Stream & Optional

文章目录JDK1.8 Stream & OptionalStream流 -Stream并行处理流 -parallelStreamIntermediate 组Map;mapToInt;mapToDouble;..filterdistinctsortedpeeklimit | skipTerminal 组forEachOrderedtoArrayreducecollectmin | maxa...

zhu714702382的博客 1005

《Java8实战》读书笔记13:Java8 与 Scala

见识一下 与 做个对比 。 这是官方提供的在线环境用于新手了解Scala :https://scastie.scala-lang.org/ scala3 如下:(莫非强制加返回类型?) 直接看个截图吧: 用于完成到的。 声明,可读写。 声明,是只读的。 可显示声明变量类型。不过Scala可以替你推断变量的类型。 2. 不可变与可变的比较 的集合只读`的。(Scala并未强制你必须使用不可变集合,只是各种暗示你接受这种风格) 可见其推荐的 就是将变化部分创建副本,并引用无变化的部分。得到

灵台方寸山斜月三星洞 729

Vavr:Java函数式编程的核心特性与应用实践

函数式编程通过数学函数的概念提升代码的简洁性与安全性,其核心原理包括不可变数据、高阶函数和纯函数。在Java生态中,Vavr作为函数式编程库,弥补了Java原生支持的不足,提供了不可变集合、模式匹配和Monadic类型等特性。这些技术显著提升了代码的健壮性和可维护性,尤其适用于复杂业务逻辑和并发场景。通过Vavr的Option、Try和Either等类型,开发者可以更优雅地处理空值和异常,而模式匹配则能有效减少条件判断的复杂度。结合Spring Boot等框架,Vavr能在生产环境中实现更声明式的编程风格,

weixin_30621959的博客 301

java8新特性-Stream和Optional

Stream Stream 是Java SE 8类库中新增的关键抽象,它被定义于 java.util.stream (这个包里有若干流类型: Stream 代表对象引用流,此外还有一系列特化流,如 IntStream,LongStream,DoubleStream等 ),Java 8 引入的的Stream主要用于取代部分Collection的操作,每个流代表一个值序列,流提供一系列常用的聚集操作,...

kk514020的博客 1605

《Java8实战》笔记(15):面向对象和函数式编程的混合-Java 8和Scala的比较(1)

给大家送一个小福利附高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、准备面试跳槽、自身职业规划迷茫的朋友们。Java 8和Scala都是整合了面向对象编程和函数式编程特性的编程语言,它们都运行于JVM之上,在很多时候可以相互操作。Scala支持对集合的抽象,支持处理的对象包括List、Set、Map、Stream、Option,这些和Java 8非常类似。不过,除此之外Scala还支持元组。

2401_84002482的博客 497
上一篇: Java中使用动态mybatis语句经典用法
下一篇: Java lamda和predicate用法例子
大树叶
博客等级 码龄12年 1171粉丝 664原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值