Java 8以上版本实现List对象非空属性求和(含嵌套空校验)
问题背景
Java 8及以上版本中,需要对List<Thing>集合存储的对象做非空属性求和,涉及的类结构如下:
public class Thing { private BigDecimal field1; private BigDecimal field2; private XYZ field3; private BigDecimal field4; } public class XYZ { private BigDecimal field5; private BigDecimal field6; }
求和规则:累加所有Thing实例的field1、field2、field3.field5三个字段的值,所有字段(包括field3对象本身)都可能为null,null值不参与累加(按0计算)。
原有实现缺少field3的空值校验,存在空指针异常风险:
public BigDecimal addFields(List<Thing> things) { return things.parallelStream() .flatMap(thing -> Stream.of(thing.getField1(), thing.getField2(), thing.getField3().getField5())) .reduce(BigDecimal.ZERO, BigDecimal::add); }
正确实现代码
以下实现兼容所有Java 8+版本,补全了全链路空值校验,保留原有并行流的执行逻辑:
import java.math.BigDecimal; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; public BigDecimal addFields(List<Thing> things) { // 集合本身为null时直接返回0,避免流操作触发NPE if (things == null) { return BigDecimal.ZERO; } return things.parallelStream() .flatMap(thing -> Stream.of( thing.getField1(), thing.getField2(), // 安全获取嵌套属性:field3为null时直接返回null,不调用getField5() Optional.ofNullable(thing.getField3()) .map(XYZ::getField5) .orElse(null) )) // 过滤所有null值,不参与求和计算 .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); }
关键逻辑说明
- 入参兜底:先判断传入的集合本身是否为null,覆盖极端入参场景
- 嵌套属性防NPE:通过
Optional包装field3的取值过程,仅当field3非空时才会调用getField5(),彻底避免嵌套取值的空指针问题 - 空值过滤:所有为null的字段值都会被过滤,不会传入
BigDecimal::add方法,求和逻辑完全符合非空属性累加的要求 - 性能无损耗:保留原有并行流的实现方式,不改动原代码的执行效率
内容的提问来源于stack exchange,提问作者Ankur Goel
相关产品推荐
相关产品推荐

