Java 8 จะส่งCollectors.toMap
a NullPointerException
หากค่าใดค่าหนึ่งเป็น 'null' ฉันไม่เข้าใจพฤติกรรมนี้แผนที่สามารถมีพอยน์เตอร์พอยน์เตอร์เป็นค่าโดยไม่มีปัญหาใด ๆ มีเหตุผลที่ดีหรือไม่ที่ค่าต่างๆจะไม่เป็นค่าว่างCollectors.toMap
?
นอกจากนี้ยังมีวิธีที่ดีของ Java 8 ในการแก้ไขปัญหานี้หรือฉันควรเปลี่ยนกลับเป็น old old for loop หรือไม่?
ตัวอย่างของปัญหาของฉัน:
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));
}
}
stacktrace:
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
- ดังที่แสดงในบรรทัดแรกของสแต็คเทรซ ปัญหาไม่Map
ได้อยู่ที่null
ค่าคงค้างไม่ได้แต่อาร์กิวเมนต์ที่สองของMap#merge
ฟังก์ชันไม่สามารถเป็นค่าว่างได้
null
เป็นปัญหาเล็กน้อยเช่นใน TreeMap อาจจะเป็นช่วงเวลาที่ดีที่จะลองOptional<Boolean>
? มิฉะนั้นแยกและใช้ตัวกรอง