Java 8 Collectors.toMaplöst ein NullPointerExceptionif 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.
nullkönnte ein Problem für einen Schlüssel sein, aber in diesem Fall ist es der Wert.
null, HashMapzum Beispiel die man haben kann nullSchlüssel und eine beliebige Anzahl von nullWerten, können Sie versuchen , ein benutzerdefinierte Erstellung Collectormit ein , HashMapanstatt dem Standard eines verwenden.
HashMap- wie in der ersten Zeile von Stacktrace gezeigt. Das Problem ist nicht, dass a Mapkeinen nullWert halten kann, sondern dass das zweite Argument der Map#mergeFunktion nicht null sein kann.
nullwar immer ein bisschen problematisch, wie in TreeMap. Vielleicht ein schöner Moment zum AusprobierenOptional<Boolean>? Andernfalls teilen und Filter verwenden.