如果其中一个值为“ null”,则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
问题内容: 我正在使用Java 8 lambda,并且想要使用 返回一个。我能想到的最好的 方法是使用一个虚拟对象并等于来调用以下方法。 我不想像我只想要的那样传递合并功能,就像下面的基本实现一样: 用来返回a 的最佳实践方法是什么? 问题答案: 我认为您没有比这更好的了: 其中lambda 与之相同,但我不能直接调用它,因为它是私有包(您当然可以总是像这样按自己的方式创建静态方法。)
如果值之一为则抛出。我不理解这种行为,映射可以包含空指针作为值没有任何问题。的值不能为null有什么好的原因吗? 还有,是否有一个很好的Java 8方法来修复这个问题,或者我应该恢复到普通的老for循环? 我的问题的一个例子: 堆栈跟踪: Java 11号还存在这个问题。
问题内容: 我有一个如下所示的集合,我想过滤掉除月末以外的所有内容。 我有以下过滤条件。返回给定月份的匹配项。 所以现在我想我必须将此过滤后的流转换回地图。我想我使用收集器来做到这一点。因此,我添加: 但是我不知道该怎么办。阅读示例会让我感到困惑。这是我当前的代码,显然不起作用。 问题答案: 除了前面的答案外,请注意,如果您不需要保留原始地图,则可以在不使用Stream API的情况下就地执行此类
我想从的中创建一个并在映射中使用相同的parentId映射列表中的所有条目,如。 我使用了但它不编译:
问题内容: 我正在尝试在以下调用中为“ keyMapper”函数参数提供更简洁的表达式: 看来我应该可以使用lambda表达式内联它,但是我无法提出一个可以编译的表达式。(我对lambda还是很陌生,所以这不足为奇。) 谢谢。 ->更新: 如已接受的答案中所述 是我一直在寻找的东西,也是我尝试过的东西。但是,问题是夜间构建的Eclipse 4.3的BETA_8是晚上出现的问题–它标记为错误。从命令