Java 8 은 값 중 하나가 'null'인 경우 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에 존재합니다.
null
은 키에 문제가 될 수 있지만이 경우에는 가치입니다.
null
, HashMap
하나 가질 수 있습니다 예를 들어 null
키와 임의의 수의 null
값을 사용자 지정을 만드는 시도 할 수 있습니다 Collector
사용 HashMap
하는 대신 기본 하나를 사용하여.
HashMap
stacktrace의 첫 번째 줄에서 볼 수 있습니다. 문제는 값을 Map
보유 할 수 없다는 것이 아니라 함수 null
의 두 번째 인수 Map#merge
가 널이 될 수 없다는 것입니다.
null
TreeMap에서와 같이 항상 약간 문제가있었습니다. 시도해 볼 수있는 좋은 순간Optional<Boolean>
? 그렇지 않으면 필터를 분리하여 사용하십시오.