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.
