Java 8 Collectors.toMap
ném một NullPointerException
nếu một trong các giá trị là 'null'. Tôi không hiểu hành vi này, bản đồ có thể chứa con trỏ null là giá trị mà không có bất kỳ vấn đề nào. Có một lý do chính đáng tại sao các giá trị không thể là null cho Collectors.toMap
?
Ngoài ra, có một cách tốt để sửa lỗi Java 8 này hay tôi nên trở lại đơn giản cho vòng lặp cũ?
Một ví dụ về vấn đề của tôi:
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));
}
}
Ngăn xếp:
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)
Vấn đề này vẫn tồn tại trong Java 11.
null
có thể là một vấn đề đối với khóa, nhưng trong trường hợp này là giá trị.
null
, HashMap
ví dụ có thể có một null
khóa và bất kỳ số lượng null
giá trị nào, bạn có thể thử tạo một tùy chỉnh Collector
bằng cách sử dụng HashMap
thay vì sử dụng một mặc định.
HashMap
- như được hiển thị trong dòng stacktrace đầu tiên. Vấn đề không phải là giá trị Map
không thể giữ null
, mà là đối số thứ hai của Map#merge
hàm không thể rỗng.
null
luôn luôn có một chút vấn đề, như trong TreeMap. Có lẽ một khoảnh khắc đẹp để thửOptional<Boolean>
? Nếu không thì tách và sử dụng bộ lọc.