Java中使用lamda表达式进行foreach,优雅处理集合List为null的情况

Java中使用lamda表达式进行foreach,优雅处理集合List为null的情况

一:举例方法

在使用Java 8及以上版本的Stream API时,如果你想要优雅地处理可能为空的List,可以使用以下方法

1、提前检查

在调用stream之前,先检查list是否为空或null。这是最直接的方法,可以避免调用stream的开销。

List<String> list = null;if (list != null && !list.isEmpty()) {list.stream().forEach(item -> {// 处理每一个item});
} else {// 处理空或null的list
}

2、Optional + Stream

使用Optional来封装可能为null的List,然后使用flatMap将其转换为一个空的Stream或List的Stream。

        Optional.ofNullable(list1)// 如果list1非空,应用List::stream方法,如果list为空,map不做任何操作.map(List::stream)// 如果list1为空,提供一个空的Stream.orElseGet(Stream::empty).forEach(item -> {// 处理每一个itemSystem.out.println(item);});

这段代码是Java中用于处理可能为空或非空的List对象的方式,旨在以函数式风格避免出现NullPointerException。下面分步解释这段代码的含义:

  1. Optional.ofNullable(list1): 这将list1包装在一个Optional对象中。如果list1null,那么得到的Optional对象将是空的。
  2. .map(List::stream): 这一步尝试将Optional中的list1转换为一个流(Stream)。如果list1是非空的,map操作将会应用传入的lambda表达式或方法引用(这里是List::stream),从而将列表转化为一个流。如果list1是空的,map操作不会做任何事情,Optional仍然为空。
  3. .orElseGet(Stream::empty): 如果前面的Optional是空的(这意味着list1null或者map操作没有执行因为Optional是空的),orElseGet方法会被调用并执行其参数(方法引用Stream::empty),该方法返回一个空的流。因此,无论list1是否为null,这一步都保证了一个流(Stream)会被返回,而不是null
  4. .forEach(item -> { ... }): 这是终端操作,会对前面步骤生成的流中的每个元素执行括号内的代码块。这里的代码块只是打印每个元素的内容。

简单来说,这段代码的作用是,无论list1是否为null或者为空列表,都能安全地对其元素进行遍历操作,而不会引发NullPointerException。如果list1为空或为null,流操作简单地不会执行任何操作,因为它会是一个空的流。

这种方法的好处在于,它不要求先检查list是否为null或空,代码更加简洁,并且在list为null时不会抛出NullPointerException。

3、Collection工具类

如果你可以使用Apache Commons Collections或Guava库,它们提供的工具类可以帮助处理null的情况。

使用Apache Commons Collections:

CollectionUtils.emptyIfNull(list).forEach(item -> {// 处理每一个item
});

使用Guava:

Iterables.emptyIfNull(list).forEach(item -> {// 处理每一个item
});

这两个方法都会安全地处理null值,如果list为null,它们会返回一个空的集合,这样就可以安全地进行迭代操作而不担心NullPointerException。

二:Optional + Stream和CollectionUtils性能比较

在这两种方式中,第二种方法使用Apache Commons Collections的CollectionUtils.emptyIfNull可能会更高效,原因如下:

  1. 简洁性CollectionUtils.emptyIfNull直接返回原始集合或空集合,不涉及额外的包装和解包步骤。它是一个简单的条件检查,如果输入为null,则返回一个预先定义的空集合。
  2. 性能OptionalmaporElseGet方法会创建更多的对象和函数调用。虽然这种开销在现代JVM上通常很小,但在大量或高频的调用中可能变得显著。
  3. 直观性CollectionUtils.emptyIfNull的表达更加直观,它清晰地表达了操作的目的——如果集合为null,则使用一个空的集合替代。这使得代码的阅读者很容易理解代码的意图。

然而,实际上,性能差异可能是微不足道的,特别是对于小型或中等规模的集合。如果性能是一个关键考虑因素,你应该基于实际的应用场景进行基准测试。很多时候,代码的清晰性和维护性可能比微小的性能差异更为重要。

在现代Java版本中(特别是Java 9及更高),Optional和流的性能得到了大幅优化。因此,如果不是在极端性能敏感的环境下

选择哪个方法更多的是:基于代码风格和可读性的考虑,而不是基于性能

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

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

相关文章

基于JAVA的社团管理系统的设计与实现

&#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;一 、设计说明 1.1 课题背景 互…

网络层详解

目录 前言 一、IP协议 1、IP协议报头 2、协议字段理解 &#xff08;1&#xff09;4位版本 &#xff08;2&#xff09;4位首部长度 &#xff08;3&#xff09;8位服务类型 &#xff08;4&#xff09;16位总长度 &#xff08;5&#xff09;标识、标志与片偏移 &#xf…

【ITK库学习】使用itk库进行图像分割(四):水平集分割

目录 1、水平集2、itkFastMarchingImageFilter 快速步进分割3、itkShapeDetectionLevelSetImageFilter 快速步进分割 1、水平集 水平集是跟踪轮廓和表面运动的一种数字化方法。基于图像的亮度均值、梯度、边缘特征的微分计算&#xff0c;进行水平集分割。在itk中&#xff0c;所…

STM32 ADC采样调试笔记

最近在搞STM32L051系列一个小MCU&#xff0c;要用这个去采集两路ADC作为输入。期间也碰到过一些问题&#xff0c;顺便记录下。 ADC采集原理不说了&#xff0c;主要采集电压&#xff0c;用数字进行细分&#xff0c;这样就可以知道输入电压多少了&#xff0c;网上也有很多相关文…

220v免驱动led驱动芯片:SM2082EDS适用于LED 球泡灯,筒灯

220V免驱动LED驱动芯片是一种电源管理芯片&#xff0c;它可以在接入220V交流电后&#xff0c;将电压转换为适合LED灯珠工作的直流电压&#xff0c;从而点亮LED灯珠。这种驱动芯片通常具有较高的转换效率和稳定性&#xff0c;能够有效地降低能耗和延长LED灯珠的寿命。 SM2082EDS…

【笔记】Helm-2 如何使用-1 chart开发提示和技巧

chart开发提示和技巧 本指南涵盖了Helm chart的开发人员在构建生产环境质量的chart时学到的一些提示和技巧。 了解你的模板功能 Helm使用了 Go模板 将你的自由文件构建成模板。Go塑造了一些内置方法&#xff0c;我们增加了一些其他的。 template package - text/template - …

Vue项目里实现json对象转formData数据

平常调用后端接口传参都是json对象&#xff0c;当提交表单遇到有附件需要传递时&#xff0c;通常是把附件上传单独做个接口&#xff0c;也有遇到后端让提交接口一并把附件传递到后端&#xff0c;这种情况需要把参数转成formData的数据&#xff0c;需要用到new FormData()。json…

【Python】科研代码学习:一

【Python】科研代码学习&#xff1a;一 前言魔方方法 __dict__, __setattr__ , __getattr__ , __getattribute__hasattr(obj, name)super()类型注解解包 unpackingzip() 函数 前言 搞科研&#xff0c;最重要的还是得看懂别人的源代码。 这就意味着python不能太差 看到比较有用…

基于SpringBoot的教学管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Go语言-无限可能的管道协程:解锁并发编程的新境界

Go语言-无限可能的管道协程&#xff1a;解锁并发编程的新境界 在Go语言中&#xff0c;协程&#xff08;Goroutine&#xff09;是一种轻量级的并发执行单位&#xff0c;它可以与其他协程并发执行&#xff0c;但不同于操作系统级别的线程。Go语言的协程由Go运行时&#xff08;Go…

​软件测试面试:关键问题解析

在软件开发领域&#xff0c;测试是确保软件质量的重要环节。面试是评估软件测试人员技能和经验的关键时刻。在一个软件测试面试中&#xff0c;面试官通常会问一系列问题来评估面试者的知识、技能和解决问题的能力。本文将介绍一些常见的软件测试面试问题&#xff0c;并给出一些…

【2024最新版】接口自动化测试基础(基础篇)

接口自动化测试基础 目录 1、什么是接口自动化测试 2、接口自动化测试要素 3、常用的落地方案 什么是接口自动化测试 PART 01 1.1什么是接口自动化测试 接口自动化测试是一种通过编写脚本或使用工具来自动化执行应用程序接口来验证接口正确性的测试方法。接口自动化测试的…

在drawio中使用BPMN2.0绘制详细的业务流程图和编排模型

在drawio中使用BPMN2.0绘制详细的业务流程图和编排模型 drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址draw.io或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功…

APP开发——目前APP开发的几种形式

关于APP开发目前已经过了火热的阶段&#xff0c;现在学习APP开发的人越来越多&#xff0c;但在实际的业务场景中&#xff0c;APP开发还是有一部分的市场需求。 所以&#xff0c;这里简单记录一下APP开发的几种思路和方案。 APP平台 首先&#xff0c;目前APP开发主要有两大平…

【Python】使用tkinter设计开发Windows桌面程序记事本(3)

上一篇&#xff1a;【Python】使用tkinter设计开发Windows桌面程序记事本&#xff08;2&#xff09;-CSDN博客 下一篇&#xff1a; 作者发炎 本文章与"记事本项目"的第一篇文章类似。这里是重新创建新的"页面设置"子窗口&#xff0c;进行开发设计。 那为…

自动化测试的三种等待方式

自动化测试的等待方式主要有三种&#xff1a;强制等待、隐式等待和显式等待。 1. 强制等待&#xff08;Sleep&#xff09; 通过在代码中使用Thread.sleep()方法来实现的&#xff0c;该方法会阻塞当前线程的执行&#xff0c;程序会暂停指定的时间。 这种方式没有条件判断&…

SpringMVC 域对象共享数据

文章目录 2、使用ModelAndView向request域对象共享数据3、使用Model向request域对象共享数据4、使用map向request域对象共享数据5、使用ModelMap向request域对象共享数据6、Model、ModelMap、Map的关系7、向session域共享数据8、向application域共享数据 1、使用ServletAPI向re…

钉钉java登录

获取token &#xff1a;API Explorer 获取部门列表&#xff1a;获取部门列表 - 钉钉开放平台

通过wireshark抓取的流量还原文件(以zip为例)

wireshark打开流量包&#xff0c;通过zip关键字查找 追踪流可查看详细信息 选中media Type右键&#xff0c; 点击导出分组字节流选项 将生成的文件进行命名&#xff0c;需要时什么格式就以什么格式后缀

ffmpeg api-alac-text.c

generate_raw_frame 这个函数接受一个 frame_data 数组作为参数&#xff0c;用于存储音频数据。i 参数表示当前帧的索引&#xff0c;sample_rate 是采样率&#xff0c;channels 是声道数&#xff0c;frame_size 是帧大小。函数使用一个简单的算法生成音频数据&#xff0c;然后…