Java8 Stream 操作 Collectors.toMap()会出现NullPointerException异常

java.lang.NullPointerException
	at java.util.HashMap.merge(HashMap.java:1225)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.example.stream.test.Test.main(Test.java:25)

当要转化的map的value值中包含空指针的情况时,会在merge()时出现。场景还原:


 Stream<User> userStream = Stream.of(new User("a", 1),
                new User("b", 2),
                new User("c", null));

userStream.collect(Collectors.toMap(User::getName, User::getAge));

解决方法

  • 设置时加判断如果是null,则设置成一个特定值;
  • 使用collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) 来构建,此时可允许null值的出现;
  • 使用Optional对值进行包装。
1、设置时加判断如果是null,则设置成一个特定值
 Map<String, Integer> collect = userStream
                .collect(Collectors.toMap(User::getName, user -> user.age == null ? 0 : user.age));

2、 使用collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) 来构建,此时可允许null值的出现
 Map<String, Integer> map = userStream
                .collect(HashMap::new, (n, v) -> n.put(v.getName(), v.getAge()), HashMap::putAll);
3、使用Optional对值进行包装
Map<String, Optional<Integer>> map = userStream
                .collect(Collectors.toMap(User::getName, user -> Optional.ofNullable(user.getAge())));
        Integer age = map.get("a").orElse(0);

你可能感兴趣的:(Java学习笔记)