public static void main(String[] args) {
Map<String, String> m = new HashMap<String, String>();
m.put("a", "One");
m.put("b", null);
toUpperKeys1(m); // NullPointerException
toUpperKeys2(m); // Working fine
toUpperKeys3(m); // NullPointerException
}
static Map<String, String> toUpperKeys1(Map<String, String> map) {
// Scenario 1 : Throwing NullPointerExpecption because Map.Entry::getValue is null
return map.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toUpperCase(), Map.Entry::getValue));
}
static Map<String, String> toUpperKeys2(Map<String, String> map) {
// Scenario 2 : Working fine
Map<String, String> newMap = new HashMap<String, String>();
map.entrySet().forEach(e -> newMap.put(e.getKey().toUpperCase(), e.getValue()));
return newMap;
}
static Map<String, String> toUpperKeys3(Map<String, String> map) {
// Scenario 3: Throwing NullPointerExpecption because e.getValue() is null
return map.entrySet().stream().collect(Collectors.toMap(e -> e.getKey().toUpperCase(), e -> e.getValue()));
}
Stacktrace:
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.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1699)
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.project.Demo.toUpperKeys1(Demo.java:25)
at com.project.Demo.main(Demo.java:17)
As Scenario 2 (for-each loop) is working fine but Scenario 1 (Map.Entry::getValue) and Scenario 3 (e -> e.getValue()) both throwing NPE.
Why toMap has this issue, while in concept of hash map null is allowed in both key and values?
Please explain.