Collectors.toMap如果其中一个值为null,则抛出NullPointerException。我不理解这种行为,映射可以包含空指针作为值而没有任何问题。对于收集器.toMap,值不能为null是否有充分的理由
另外,是否有一种很好的Java8方法来解决这个问题,或者我应该恢复到普通的旧for循环
我的问题的一个例子:
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Map;
导入java.util.stream.collector;
课堂答案{
私有int-id;
私有布尔答案;
答复(){
}
答案(整数id,布尔答案){
this.id=id;
这个答案=答案;
}
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}
公共布尔getAnswer(){
返回答案;
}
公共void setAnswer(布尔答案){
这个答案=答案;
}
}
公共班机{
公共静态void main(字符串[]args){
列表<;应答>;应答列表=新阵列列表<;>;();
添加(新答案(1,正确));
添加(新答案(2,正确));
添加(新答案(3,空));
映射<;整数,布尔>;应答映射=
回答者名单
.stream()
.collect(Collectors.toMap(Answer::getId,Answer::getAnswer));
}
}
堆栈跟踪:
线程中的异常”;“主要”;java.lang.NullPointerException
位于java.util.HashMap.merge(HashMap.java:1216)
lambda$toMap$168(Collectors.java:1320)
位于java.util.stream.Collectors$$Lambda$5/1528902577.accept(未知源)
位于java.util.stream.ReduceOps$3ReduceInSink.accept(ReduceOps.java:169)
位于java.util.ArrayList$ArrayListSpliterator.ForEachLeving(ArrayList.java:1359)
位于java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
位于java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
位于java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
位于java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
位于java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
Main.Main(Main.java:48)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:483)
位于com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
这个问题在Java11中仍然存在
您可以解决这个问题已知错误
地图<;整数,布尔值>;collect=list.stream()
.collect(HashMap::new,(m,v)->m.put(v.getId(),v.getAnswer()),HashMap::putAll);
虽然没有那么漂亮,但它很管用。结果:
1:正确
2:对
3:null
编辑:
与Collectors.toMap不同,如果您多次使用相同的键,这将以静默方式替换值,正如@mmdemirbas在注释中指出的那样。如果你不想这样,请查看评论中的链接