带有空条目值的Collectors.toMap中的NullPointerException [英] NullPointerException in Collectors.toMap with null entry values

查看:126
本文介绍了带有空条目值的Collectors.toMap中的NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Collectors.toMap 会引发 NullPointerException .我不了解这种行为,地图可以包含空指针作为值,而不会出现任何问题.是否有充分的理由为什么 Collectors.toMap 的值不能为null?

Collectors.toMap throws a NullPointerException if one of the values is null. I don't understand this behaviour, maps can contain null pointers as value without any problems. Is there a good reason why values cannot be null for Collectors.toMap?

此外,是否有解决此问题的Java 8不错的方法,还是我应该恢复到普通的for循环?

Also, is there a nice Java 8 way of fixing this, or should I revert to plain 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:

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中仍然存在.

This problem still exists in Java 11.

推荐答案

您可以解决此 OpenJDK中的已知错误:

Map<Integer, Boolean> collect = list.stream()
        .collect(HashMap::new, (m,v)->m.put(v.getId(), v.getAnswer()), HashMap::putAll);

它不是很漂亮,但是可以工作.结果:

It is not that much pretty, but it works. Result:

1: true
2: true
3: null

( ="教程对我的帮助最大.)

(this tutorial helped me the most.)

Collectors.toMap 不同,如果@mmdemirbas在注释中指出多次,则如果您多次具有相同的键,这将以静默方式替换值.如果您不希望这样做,请查看评论中的链接.

Unlike Collectors.toMap, this will silently replace values if you have the same key multiple times, as @mmdemirbas pointed out in the comments. If you don't want this, look at the link in the comment.

这篇关于带有空条目值的Collectors.toMap中的NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆