JDK8 Lambda过滤映射时出现NullPointerException问题求助
解决Lambda表达式中的NullPointerException问题
首先,咱们先拆解下你这段代码里可能触发NPE的几个风险点:
object可能为nullobject.getInfo()返回的Map可能为nullobject.getInfo().get("HAIR_STYLE")可能取不到值返回null- 过滤后的列表为空时,
get(0)会抛出NoSuchElementException(这也是潜在的异常风险,得一起处理)
Java 8引入的Optional就是专门用来解决这类空指针问题的,能让你用链式调用的方式优雅处理空值,不用写一堆嵌套的if判断。下面是优化后的代码:
return Optional.ofNullable(object) .map(obj -> obj.getInfo()) .map(infoMap -> infoMap.get("HAIR_STYLE")) .map(Number::intValue) .flatMap(targetId -> listOfPossibleHaircuts.stream() .filter(p -> Optional.ofNullable(p) .map(ParameterDetail::getParameterDetailId) .map(Number::intValue) .orElse(-1) == targetId) .map(ParameterDetail::getParameterValue) .findFirst()) .orElse(null); // 可根据业务需求替换成默认值,比如空字符串""
咱们逐行解释下这段代码的逻辑:
Optional.ofNullable(object):把可能为null的object包装成Optional容器,避免直接调用方法时触发NPE- 连续的
map调用:每一步只有当前容器内的对象不为null时,才会执行后续的方法调用;如果某一步返回null,整个链会直接跳过后续操作,走到最后的兜底逻辑 flatMap里的流式处理:- 对每个
ParameterDetail也用Optional.ofNullable包装,避免p为null时调用getParameterDetailId()抛NPE - 用
orElse(-1)给一个业务上不可能出现的默认值,确保即使p的参数ID为null,也不会触发NPE,同时不会错误匹配目标ID - 用
findFirst()替代collect(Collectors.toList()).get(0),避免过滤后无元素时抛出异常
- 对每个
orElse(null):如果整个链中任何一步为空,就返回null(你也可以根据业务需求改成返回空字符串或者其他合理默认值)
另外还有两个小建议:
- 如果
ParameterDetail的getParameterDetailId()返回的是Integer,建议用equals()代替==比较值,避免因为Integer缓存范围(-128到127)导致的意外不相等问题 - 如果业务上不允许没有匹配元素的情况,可以把
orElse(null)改成orElseThrow(() -> new IllegalArgumentException("未找到匹配的发型参数")),抛出更明确的业务异常
内容的提问来源于stack exchange,提问作者hephestos
相关产品推荐
相关产品推荐

