文章目录
- Stream Collectors.toMap 当value为null时报空指针
- 问题
- 源码
- 解决
Stream Collectors.toMap 当value为null时报空指针
问题
java">public class Demo {public static void main(String[] args) {List<Test> list = new ArrayList<>();list.add(new Test("code1", "name1"));list.add(new Test("code2", null));Map<String, String> map = list.stream().collect(Collectors.toMap(Test::getCode, Test::getName));System.out.println(map);}
}@Data
@AllArgsConstructor
class Test {private String code;private String name;
}
执行结果:
java">Exception in thread "main" java.lang.NullPointerExceptionat java.util.HashMap.merge(HashMap.java:1226)at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)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:566)at com.scj.test.Demo.main(Demo.java:15)
源码
java">public final class Collectors {public static <T, K, U>Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper) {return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);}public static <T, K, U, M extends Map<K, U>>Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,Function<? super T, ? extends U> valueMapper,BinaryOperator<U> mergeFunction,Supplier<M> mapSupplier) {BiConsumer<M, T> accumulator= (map, element) -> map.merge(keyMapper.apply(element),valueMapper.apply(element), mergeFunction);return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);}
}
Collectors.toMap 最终会调用 Map 的 merge 方法,这里会对value进行判空,如果为空,则抛出空指针异常。
java">public interface Map<K,V> {default V merge(K key, V value,BiFunction<? super V, ? super V, ? extends V> remappingFunction) {Objects.requireNonNull(remappingFunction);Objects.requireNonNull(value); // 这里会对value判空,如果为空,则抛出NPEV oldValue = get(key);V newValue = (oldValue == null) ? value :remappingFunction.apply(oldValue, value);if(newValue == null) {remove(key);} else {put(key, newValue);}return newValue;}
}
解决
方案一:采用下面这种写法
java">Map<String, String> collect = list.stream().collect(HashMap::new, (m, v) -> m.put(v.getCode(), v.getName()), HashMap::putAll
);
方案二:对value进行判空,并给一个默认值
java">Map<String, String> map = list.stream().collect(Collectors.toMap(Test::getCode, e -> Optional.ofNullable(e.getName()).orElse("")
));