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和流的性能得到了大幅优化。因此,如果不是在极端性能敏感的环境下

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

相关推荐
程序伍六七4 分钟前
day16
开发语言·c++
wkj0018 分钟前
php操作redis
开发语言·redis·php
武子康10 分钟前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康12 分钟前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
极客代码13 分钟前
【Python TensorFlow】进阶指南(续篇三)
开发语言·人工智能·python·深度学习·tensorflow
苏-言19 分钟前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
土豆湿19 分钟前
拥抱极简主义前端开发:NoCss.js 引领无 CSS 编程潮流
开发语言·javascript·css
界面开发小八哥26 分钟前
更高效的Java 23开发,IntelliJ IDEA助力全面升级
java·开发语言·ide·intellij-idea·开发工具
草莓base39 分钟前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring
Allen Bright1 小时前
maven概述
java·maven