Java 8 Optional类详解:避免空指针与链式编程

需积分: 9 1 下载量 19 浏览量 更新于2024-08-27 收藏 8KB MD 举报
"这篇文档主要介绍了Java中的Optional类,包括其概述、好处以及一系列常用方法的说明,旨在帮助开发者更好地理解和使用Optional类来避免空指针异常,并支持函数式编程和链式调用。" 在Java 8及更高版本中,`Optional` 类是一个容器对象,它可能包含或不包含非null值。这个设计主要是为了防止空指针异常(NullPointerException),并鼓励更清晰的代码结构。使用 `Optional` 可以使代码更具有表达性,尤其是当处理可能为null的返回值时。 ### Optional类的优势 1. **防止空指针异常**:通过使用 `Optional`,可以在编译时就检测到潜在的空指针异常,而不是在运行时。这提高了代码的健壮性和可靠性。 2. **支持函数型接口**:`Optional` 与lambda表达式和其他函数型接口如`Consumer`、`Supplier`很好地配合,使得代码更简洁,更易于理解。 3. **链式编程**:`Optional` 支持链式调用,使得代码更具有可读性,同时降低了嵌套条件语句的复杂性。 ### Optional类的常用方法 1. **Optional.of(T t)**:此方法用于创建一个包含非null值的 `Optional` 实例。如果传入的值为null,会抛出 `NullPointerException`。 2. **Optional.empty()**:创建一个空的 `Optional` 实例,不包含任何值。 3. **Optional.ofNullable(T t)**:这是最常用的构造方法,如果传入的值为null,它将返回一个空的 `Optional`,否则返回一个包含该值的 `Optional` 实例。 4. **isPresent()**:检查 `Optional` 是否包含值。如果包含,返回 `true`;否则,返回 `false`。 5. **ifPresent(Consumer<T> consumer)**:如果 `Optional` 包含值,就使用传入的 `Consumer` 对象处理该值,不会抛出异常。 6. **get()**:返回 `Optional` 中的值。如果值不存在,会抛出 `NoSuchElementException`。 7. **orElse(T t)**:如果 `Optional` 有值,返回该值;否则,返回指定的默认值 `t`。 8. **orElseGet(Supplier<? extends T> supplier)**:如果 `Optional` 有值,返回该值;否则,使用 `Supplier` 获取一个值。 9. **orElseThrow(Supplier<? extends X> exceptionSupplier)**:如果 `Optional` 有值,返回该值;否则,使用 `Supplier` 创建并抛出一个异常。 ### 示例代码解析 在示例代码中,展示了如何使用 `Optional` 避免传统的空指针检查。传统方式需要对对象进行多次null检查,而使用 `Optional` 后,可以通过 `ofNullable()`、`filter()` 和 `ifPresent()` 方法实现相同的功能,但代码更加简洁且易于理解。 在链式调用中,`filter(x->x.getName()=="张三")` 检查 `Person` 的名字是否为 "张三",如果满足条件,`ifPresent(System.out::println)` 将打印出 `Person` 对象的详细信息。如果 `Person` 为null或名字不为 "张三",则什么也不会发生。 `Optional` 类为Java开发者提供了一种优雅的方式来处理可能为null的对象,增强了代码的可读性和安全性。通过熟练掌握 `Optional` 的使用,可以编写出更高质量、更少错误的代码。

for (BdFindOutPlanGroupDTO comDTO : result) { Result<FeignOrgDTO> feignOrgDTOResult = remoteIpmpOrgService.getInfoById(comDTO.getCompanyId().toString()); if (StringUtils.isNotNull(feignOrgDTOResult.getData())) { if (StringUtils.isNotNull(feignOrgDTOResult.getData())) { comDTO.setCompanyName(feignOrgDTOResult.getData().getOrgName()); } else { comDTO.setCompanyName(comDTO.getCompanyId().toString()); } } else { comDTO.setCompanyName(comDTO.getCompanyId().toString()); } BdFindOutPlanGroupDtlQueryDTO findOutPlanGroupDtlQueryDTO = new BdFindOutPlanGroupDtlQueryDTO(); findOutPlanGroupDtlQueryDTO.setFindOutPlanGroupId(Long.parseLong(comDTO.getFindOutPlanGroupId())); List<BdFindOutPlanGroupDtlDO> bdFindOutPlanGroupDtlDOS = findOutPlanGroupDtlMapper.selectList(findOutPlanGroupDtlQueryDTO); List<BdFindOutPlanGroupDtlDTO> dtoList = BeanUtils.copyToList(bdFindOutPlanGroupDtlDOS, BdFindOutPlanGroupDtlDTO.class); //获取项目id与项目名称对应关系 if (StringUtils.isNotEmpty(dtoList)) { List<Long> projectIdList = dtoList.stream().map(BdFindOutPlanGroupDtlDTO::getProjectId).collect(Collectors.toList()); ApiMdProjectDTO apiMdProjectDTO = new ApiMdProjectDTO(); apiMdProjectDTO.setProjectIds(projectIdList.stream().map(x -> x + "").collect(Collectors.toList())); Result<List<ApiMdProjectDTO>> projectInfoList = remoteProjecctService.listProject(apiMdProjectDTO); Map<String, String> stringStringMap = CollectionUtils.toMap( projectInfoList.getData(), ApiMdProjectDTO::getProjectId, ApiMdProjectDTO::getProjectName ); //将从其他表获取的数值做填充 dtoList.forEach(d -> { //如果md_project表未查询到名称,则显示id d.setProjectName(Optional.ofNullable(stringStringMap.get(d.getProjectId().toString())).orElse(d.getProjectId().toString())); }); } comDTO.setFindOutPlanGroupDtlDTOS(dtoList); } 代码优化

2023-06-07 上传
2023-07-11 上传