开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
All elements are null
分享在开发的过程中遇到一个隐秘性极高的bug,通常我们在开发过程中都会用到List集合,我们会接受JAVA对象、字符串,也会接收前端过来的参数,有时候我们会用Java8,lamda表达式对集合的某一个字段进行筛选。
比如:
//通过lamda表达式对对象里的字段进行过滤,返回字符串集合
List<String> relationOrderNos = slaughterUpdateReqDTO.getReceivableFees().stream().map(ReceivableFeeDTO::getRelationOrderNo).collect(Collectors./toList/());
正常会对集合进行判空,不为空在进行业务逻辑操作,然后我就遇到了个大无语事件,活活坑了我几个小时。
场景
前端调我接口会在对象里面传参数,如果不输入text,这个字段在请求后端接口的时候,就不会给到我,甚至字段名也不会有,这…. 反正我觉得这样做不是很合理,最起码不输入的情况下,字段名也是要给的。
这个字段是relationOrderNo然后我就会对这个字段进行过滤,用List进行接收,然后测试就问我,这字段我就没输入为什么还是返回业务的异常处理。 然后我就告诉测试,不可能,绝对不可能,你不输入我压根就不会过滤出来,List里面就是空的。
Debug代码
然后我通过debug代码后,我就打脸了,这个List 的size既然是1,那么通过CollectionUtil./isNotEmpty/判断就不可能为空,然后我看集合里面,竟然是 All elements are null。
后面我才想到ArrayList是允许存在null,这就可以解释通了,虽然里面是null,但是是有长度的,就无法用非空来判断,这里深深的给我上了一课。
解决方法
后面我换了一种写法,也是通过lamda表达式,判断集合中字符串不为空,并且把字段进行映射,这样如果没有那么就映射不到,那么返回的List集合就是空的,就可以对集合进行非空判断了。
List<String> relationOrderNos = slaughterUpdateReqDTO.getReceivableFees().stream().filter(t -> StringUtils.isEmpty(t.getRelationOrderNo())).map(ReceivableFeeDTO::getRelationOrderNo).collect(Collectors.toList());
这个坑应该在日常的开发中还是比较常见,也希望小伙伴们能避开此坑,不要犯同样的错误。