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 -> {
                    // 处理每一个item
                    System.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和流的性能得到了大幅优化。因此,如果不是在极端性能敏感的环境下

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

相关推荐
The Future is mine25 分钟前
Python计算经纬度两点之间距离
开发语言·python
Enti7c26 分钟前
HTML5和CSS3的一些特性
开发语言·css3
腥臭腐朽的日子熠熠生辉31 分钟前
解决maven失效问题(现象:maven中只有jdk的工具包,没有springboot的包)
java·spring boot·maven
爱吃巧克力的程序媛33 分钟前
在 Qt 创建项目时,Qt Quick Application (Compat) 和 Qt Quick Application
开发语言·qt
ejinxian33 分钟前
Spring AI Alibaba 快速开发生成式 Java AI 应用
java·人工智能·spring
杉之38 分钟前
SpringBlade 数据库字段的自动填充
java·笔记·学习·spring·tomcat
圈圈编码1 小时前
Spring Task 定时任务
java·前端·spring
俏布斯1 小时前
算法日常记录
java·算法·leetcode
独好紫罗兰1 小时前
洛谷题单3-P5719 【深基4.例3】分类平均-python-流程图重构
开发语言·python·算法
27669582921 小时前
美团民宿 mtgsig 小程序 mtgsig1.2 分析
java·python·小程序·美团·mtgsig·mtgsig1.2·美团民宿