我将Java 11流的结果放入Collectors.toMap(keyMapper, valueMapper)
收集器中。碰巧我的值映射器(lambda)返回一个空值,结果是NullPointerException
,这令人惊讶。
java.lang.NullPointerException
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at java.base/java.util.stream.Collectors.lambda$uniqKeysMapAccumulator$1(Collectors.java:178)
at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.base/java.util.TreeMap$EntrySpliterator.forEachRemaining(TreeMap.java:2962)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at [my code]
对Objects.requireNonNull
的致命呼叫位于Collectors.uniqKeysMapAccumulator()
中:
private static <T, K, V>
BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
return (map, element) -> {
K k = keyMapper.apply(element);
V v = Objects.requireNonNull(valueMapper.apply(element));
V u = map.putIfAbsent(k, v);
if (u != null) throw duplicateKeyException(k, u, v);
};
}
关键表达为Objects.requireNonNull(valueMapper.apply(element))
。
为什么收集器要求映射值不为空?这是实现中的错误吗?
Map.merge
operation is required to reject null
values。给Collectors.toMap()
的{{1}}方法的文档说明mergeFunction
将使用它。但是,2参数Map.merge
方法的Collectors
文档(没有toMap()
)没有声明值必须为非空,也没有声明{{ 1}}完全被人感染。