Stream中toMap引发NullPointerException
1、引发NullPointerException的代码如下:
List<SelfSettlementCardInfoDto> selfSettlementCardInfoDtos =selfCardAdapterManager.listSelfSettlementCardInfoDtoByCardIds(queryDto.getPartnerId(), cardIds, false);
Map<Long, String> cardIdCardNoTokenMap = selfSettlementCardInfoDtos.stream().collect(Collectors.toMap(SelfSettlementCardInfoDto::getId, SelfSettlementCardInfoDto::getCardNoToken));
其中selfSettlementCardInfoDtos中的cardNoToken有可能为空。
习惯性地认为hashmap支持指针和值为null,而stream中的toMap()方法也是用HashMap实现的,因此看到这个地方报NullPointerException的时候,很奇怪。
2、分析
查看toMap()源码:
进入merge()方法:
看到:
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
大概就知道了:toMap方法不允许null值
因此:
Stream中toMap不允许key和value为null
3、改进方法:
1、不用toMap方法
Map<Long, String> cardIdCardNoTokenMap = selfSettlementCardInfoDtos.stream().collect(HashMap::new, (m,v)->m.put(v.getId(), v.getCardNoToken()), HashMap::putAll);
2、在流中加上判空过滤
Map<Long, String> cardIdCardNoTokenMap = selfSettlementCardInfoDtos.stream().filter(t -> t.getCardNoToken() != null).collect(Collectors.toMap(SelfSettlementCardInfoDto::getId, SelfSettlementCardInfoDto::getCardNoToken));
Stream的执行流程
Stream流中,每一个遍历的对象执行完所有的操作后,才会对下一个对象进行操作。
@Testpublic void test10() {String[] s={"a","b","c","d"};List<String> collect = Stream.of(s).filter(s1 -> {System.out.println("s1");return s1.length() == 1;}).filter(s2 -> {System.out.println("s2");return s2.length() == 1;}).collect(Collectors.toList());System.out.println(collect);}
结果如下:
s1
s2
s1
s2
s1
s2
s1
s2
[a, b, c, d]