如果其中一个值为“ null”,则Java 8 Collectors.toMap会抛出a NullPointerException。我不了解这种行为,地图可以包含空指针作为值,而没有任何问题。是否有充分的理由为何值不能为null Collectors.toMap?
Java 8 Collectors.toMap
a NullPointerException
null Collectors.toMap
另外,是否有解决此问题的不错的Java 8方法,还是应该将其恢复为普通的for循环?
我的问题的一个例子:
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)); } }
堆栈跟踪:
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)
Java 11中仍然存在此问题。
你可以使用以下方法来解决OpenJDK中的此已知错误:
Map<Integer, Boolean> collect = list.stream() .collect(HashMap::new, (m,v)->m.put(v.getId(), v.getAnswer()), HashMap::putAll);
它不是很漂亮,但是可以工作。结果:
1: true 2: true 3: null