Java 8 Collectors.toMap
löst ein NullPointerException
if aus, wenn einer der Werte 'null' ist. Ich verstehe dieses Verhalten nicht, Maps können problemlos Nullzeiger als Wert enthalten. Gibt es einen guten Grund, warum Werte nicht null sein können Collectors.toMap
?
Gibt es auch eine gute Java 8-Methode, um dies zu beheben, oder sollte ich auf die alte for-Schleife zurückgreifen?
Ein Beispiel für mein Problem:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class Answer {
private int id;
private Boolean answer;
Answer() {
}
Answer(int id, Boolean answer) {
this.id = id;
this.answer = answer;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Boolean getAnswer() {
return answer;
}
public void setAnswer(Boolean answer) {
this.answer = answer;
}
}
public class Main {
public static void main(String[] args) {
List<Answer> answerList = new ArrayList<>();
answerList.add(new Answer(1, true));
answerList.add(new Answer(2, true));
answerList.add(new Answer(3, null));
Map<Integer, Boolean> answerMap =
answerList
.stream()
.collect(Collectors.toMap(Answer::getId, Answer::getAnswer));
}
}
Stacktrace:
Exception in thread "main" java.lang.NullPointerException
at java.util.HashMap.merge(HashMap.java:1216)
at java.util.stream.Collectors.lambda$toMap$168(Collectors.java:1320)
at java.util.stream.Collectors$$Lambda$5/1528902577.accept(Unknown Source)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1359)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
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:499)
at Main.main(Main.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Dieses Problem besteht weiterhin in Java 11.
null
könnte ein Problem für einen Schlüssel sein, aber in diesem Fall ist es der Wert.
null
, HashMap
zum Beispiel die man haben kann null
Schlüssel und eine beliebige Anzahl von null
Werten, können Sie versuchen , ein benutzerdefinierte Erstellung Collector
mit ein , HashMap
anstatt dem Standard eines verwenden.
HashMap
- wie in der ersten Zeile von Stacktrace gezeigt. Das Problem ist nicht, dass a Map
keinen null
Wert halten kann, sondern dass das zweite Argument der Map#merge
Funktion nicht null sein kann.
null
war immer ein bisschen problematisch, wie in TreeMap. Vielleicht ein schöner Moment zum AusprobierenOptional<Boolean>
? Andernfalls teilen und Filter verwenden.