Java Lambda空指针四种主流处理方案总结

 更新时间:2026年07月16日 10:51:28   作者:devilnumber  
这篇文章主要介绍了Java Lambda空指针四种主流处理方案的相关资料,Optional链式消除多层空值、Stream过滤集合null元素、三元表达式快速兜底,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

Lambda 开发最容易 NPE:集合为空、元素为 null、字段为 null,

常用四种:if判空、Optional、Stream过滤、函数式空安全

优先用 Optional + Stream,替代大量 if,符合 Lambda 函数式思想。

一、方案 1:传统 if 判空(不推荐在 Lambda 大量使用,过渡)

原理

提前 null 判断再执行逻辑,最原始。

User user = null;
if(user != null){
    System.out.println(user.getName());
}

缺点:代码臃肿,链式流式代码中割裂 Lambda 风格,大量 if 重复造轮子。

适用:简单单行代码,流式处理禁用

二、方案 2:Optional(Lambda 标配,首选,JDK8)【重点背诵】

核心定位

容器对象,用来封装可能为 null 的值,杜绝显式 if==null,函数式处理空,配合 Lambda

四个核心 API(必背 4 个)

  1. Optional.ofNullable(obj):可以传 null(日常 99% 用)
  2. Optional.of(obj):入参不能 null,空直接 NPE
  3. orElse(默认值):为空返回默认值
  4. orElseGet(Supplier):为空执行 Lambda 生成默认(懒加载,性能优)
  5. orElseThrow():空抛异常
  6. map(Function):安全获取嵌套属性(解决多层对象空指针,重中之重)
  7. ifPresent(Consumer):非空才执行 Lambda 逻辑

实战 1:普通对象空安全

User user = null;
// 非空执行打印
Optional.ofNullable(user).ifPresent(u-> System.out.println(u.getName()));
// 空给默认对象
User defUser = Optional.ofNullable(user).orElse(new User("默认"));
// Lambda懒创建默认(推荐)
User user2 = Optional.ofNullable(user).orElseGet(()->new User());

实战 2:多层对象(最经典,解决连环 NPE)

// user→Address→city,多层任意一层null都不报错
String city = Optional.ofNullable(user)
        .map(User::getAddress)
        .map(Address::getCity)
        .orElse("未知城市");

map 特点:中间任意返回 null,后续 map 不再执行,直接走到 orElse。

实战 3:空则抛异常

User u = Optional.ofNullable(user).orElseThrow(()->new RuntimeException("用户不存在"));

Optional 使用口诀

ofNullable 包对象,map 逐层拿属性;ifPresent 非空执行,orElse 兜底默认值。

三、方案 3:Stream filter 过滤 null(集合遍历 Lambda 空处理,高频)

场景:List 集合中元素为 null / 对象字段为 null

filter(Objects::nonNull) 过滤空元素,再执行后续 map/forEach。

List<User> userList = Arrays.asList(null,new User("张三"),null,new User("李四"));

// 过滤null元素,再Lambda处理
userList.stream()
        .filter(Objects::nonNull) // 剔除集合里null元素
        .forEach(u-> System.out.println(u.getName()));

// 字段为空过滤
userList.stream()
        .filter(Objects::nonNull)
        .filter(u->u.getName()!=null)
        .map(User::getName)
        .collect(Collectors.toList());

拓展:Objects.nonNull()/isNull()JDK8 工具方法,Lambda 筛选标配。

四、方案 4:函数式默认值 + 三元(简单字段兜底)

搭配 Lambda、Stream map 中兜底

// 字段为空返回默认字符串
List<String> names = userList.stream()
        .filter(Objects::nonNull)
        .map(u->u.getName()==null ? "无名":u.getName())
        .collect(Collectors.toList());

五、四种方案选型对比(背诵)

表格

方案适用场景优点缺点
if 判空简单零散代码易懂破坏流式 Lambda,代码冗余
Optional单个对象、多层级属性获取链式优雅、函数式、无 if不能直接处理集合
Stream filter集合批量处理批量过滤空,流式一体化只管集合元素,不适合单个对象
三元表达式单个字段快速兜底极简多层嵌套可读性差

项目统一规范(工作落地)

  1. 单个 POJO、多级属性:统一用 Optional.map ()
  2. List 集合流式处理:开头 filter (Objects::nonNull)
  3. 简单字段赋值:三元表达式快速兜底
  4. 杜绝大量 if (user!=null)

六、高频综合实战(项目标准写法)

需求:用户列表,过滤空用户、空姓名,获取城市,空城市赋值【未知】

List<String> cityList = userList.stream()
        .filter(Objects::nonNull) // 剔除null用户
        .map(user-> Optional.ofNullable(user.getAddress()).map(Address::getCity).orElse("未知"))
        .collect(Collectors.toList());

七、易错坑(面试常问)

  1. Optional.of()不能传 null,必 NPE,一律优先ofNullable
  2. orElse:不管空不空,对象提前创建;orElseGet:只有空才创建,资源重对象优先 orElseGet
  3. Optional 是容器,不能用 ==null 判断容器,容器永远非空,空是内部值为空。

八、终极背诵总结

单个对象多层空,Optional 链式 map;集合遍历有空值,Stream filter 先剔除;简单字段缺默认,三元表达式兜底;少写 if 少判空,Lambda 风格要统一。

到此这篇关于Java Lambda空指针四种主流处理方案总结的文章就介绍到这了,更多相关Java Lambda空指针处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java用单向环形链表来解决约瑟夫环Josepfu问题

    Java用单向环形链表来解决约瑟夫环Josepfu问题

    如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表,通俗讲就是把尾节点的下一跳指向头结点
    2021-10-10
  • Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

    Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

    循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,这篇文章主要介绍了Spring Boot循环依赖原理、解决方案与最佳实践(全解析),需要的朋友可以参考下
    2025-04-04
  • Java 实现判定顺序表中是否包含某个元素(思路详解)

    Java 实现判定顺序表中是否包含某个元素(思路详解)

    这篇文章主要介绍了Java 实现判定顺序表中是否包含某个元素,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • 详解SpringBoot读取Yml配置文件的3种方法

    详解SpringBoot读取Yml配置文件的3种方法

    本文主要介绍了详解SpringBoot读取Yml配置文件的3种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java中常用的设计模式之装饰器模式详解

    Java中常用的设计模式之装饰器模式详解

    这篇文章主要为大家详细介绍了Java中常用的设计模式之装饰器模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解

    SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解

    这篇文章主要介绍了SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 用SpringBoot Admin监控SpringBoot程序

    用SpringBoot Admin监控SpringBoot程序

    这篇文章主要介绍了用SpringBoot Admin监控SpringBoot程序,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2020-10-10
  • SpringBoot入门实现第一个SpringBoot项目

    SpringBoot入门实现第一个SpringBoot项目

    今天我们一起来完成一个简单的SpringBoot(Hello World)。就把他作为你的第一个SpringBoot项目。具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • shiro编码和加密代码详解

    shiro编码和加密代码详解

    Shiro提供了base64和16进制字符串编码/解码的API支持,方便一些编码解码操作。下面通过实例代码给大家详解shiro编码和加密知识,感兴趣的朋友一起看看吧
    2017-09-09
  • Java后端向前端返回文件流实现下载功能

    Java后端向前端返回文件流实现下载功能

    后端可以使用Java中servlet提供的HttpServletResponse,核心步骤是要设置响应的数据类型,设置为某一类文件类型或二进制格式,以及响应头,然后用ServletOutputStream将文件以流的形式发送到前端,本文介绍Java后端向前端返回文件流实现下载功能,感兴趣的朋友一起看看吧
    2023-12-12

最新评论