I am putting the results of a Java 11 stream into a Collectors.toMap(keyMapper, valueMapper)
collector. It so happens that my value-mapper (lambda) returns a null value, resulting in a NullPointerException
, which is surprising.
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]
The fatal call to Objects.requireNonNull
is in 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);
};
}
The crucial expression being Objects.requireNonNull(valueMapper.apply(element))
.
Why is the collector requiring that map values are non null? Is this a bug in the implementation?
The Map.merge
operation is required to reject null
values. The documentation for the Collectors.toMap()
methods that are given a mergeFunction
state that it will be used by Map.merge
. However, the Collectors
documentation for the 2-argument toMap()
methods (which do not have a mergeFunction
) does not state that values must be non-null, nor does it state that Map.merge
is invloved at all.