Stream中toMap引发NullPointerException____Stream的执行流程

x33g5p2x  于2021-12-24 转载在 其他  
字(1.5k)|赞(0)|评价(0)|浏览(367)

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流中,每一个遍历的对象执行完所有的操作后,才会对下一个对象进行操作。

@Test
    public 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]

相关文章