Le Java 8 Collectors.toMaplance un NullPointerExceptionsi l'une des valeurs est 'null'. Je ne comprends pas ce comportement, les cartes peuvent contenir des pointeurs nuls comme valeur sans aucun problème. Y a-t-il une bonne raison pour laquelle les valeurs ne peuvent pas être nulles Collectors.toMap?
De plus, y a-t-il une bonne façon de résoudre ce problème en Java 8, ou devrais-je revenir à la boucle ancienne pour la boucle?
Un exemple de mon problème:
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));
}
}
Trace de la pile:
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)
Ce problème existe toujours dans Java 11.
nullpourrait être un problème pour une clé, mais dans ce cas, c'est la valeur.
null, HashMappar exemple, peuvent avoir une nullclé et un nombre quelconque de nullvaleurs, vous pouvez essayer de créer un personnalisé en Collectorutilisant un HashMapau lieu d'utiliser celui par défaut.
HashMap- comme indiqué dans la première ligne de stacktrace. Le problème n'est pas qu'une valeur Mapne peut pas contenir null, mais que le deuxième argument de la Map#mergefonction ne peut pas être nul.
nulla toujours été un peu problématique, comme dans TreeMap. Peut-être un bon moment pour essayerOptional<Boolean>? Sinon, divisez et utilisez le filtre.