欢迎光临
我们一直在努力

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

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 个)

  • Optional.ofNullable(obj):可以传 null(日常 99% 用)
  • Optional.of(obj):入参不能 null,空直接 NPE
  • orElse(默认值):为空返回默认值
  • orElseGet(Supplier):为空执行 Lambda 生成默认(懒加载,性能优)
  • orElseThrow():空抛异常
  • map(Function):安全获取嵌套属性(解决多层对象空指针,重中之重)
  • 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 集合批量处理 批量过滤空,流式一体化 只管集合元素,不适合单个对象
    三元表达式 单个字段快速兜底 极简 多层嵌套可读性差

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

  • 单个 POJO、多级属性:统一用 Optional.map ()
  • List 集合流式处理:开头 filter (Objects::nonNull)
  • 简单字段赋值:三元表达式快速兜底
  • 杜绝大量 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());

    七、易错坑(面试常问)

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

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

    赞(0)
    未经允许不得转载:171主机测评 » Java Lambda + 空指针四种主流处理方案
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址