当前位置: 首页 > 知识库问答 >
问题:

Collectors.tomap中的NullPointerException具有空条目值

张照
2023-03-14

Collectors.tomap如果值之一为NullPointerException则抛出NullPointerException。我不理解这种行为,映射可以包含空指针作为值没有任何问题。collectors.tomap的值不能为null有什么好的原因吗?

还有,是否有一个很好的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号还存在这个问题。

共有1个答案

司徒瀚
2023-03-14

您可以通过以下方法在OpenJDK中解决这个已知的bug:

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

(这个教程对我的帮助最大。)

编辑:

collectors.tomap不同的是,如果您多次使用相同的键,这将默默地替换值,正如@mmdemirbas在注释中指出的那样。如果你不想这样,看看评论中的链接。

 类似资料:
  • 问题内容: 如果其中一个值为“ null”,则会抛出。我不了解这种行为,地图可以包含空指针作为值,而没有任何问题。是否有充分的理由为何值不能为? 另外,是否有解决此问题的不错的Java 8方法,还是应该将其恢复为普通的for循环? 我的问题的一个例子: 堆栈跟踪: Java 11中仍然存在此问题。 问题答案: 你可以使用以下方法来解决OpenJDK中的此已知错误: 它不是很漂亮,但是可以工作。结果

  • 我正在尝试根据“年”和“发票”列加入两个pyspark数据帧,如下所示。但是如果df1中缺少“年”,那么我需要仅根据“发票”加入 DF1: df2: 预期输出: 我可以按如下方式加入df1和df2(仅基于“年份和发票”列)。如果df1中缺少年份,我需要添加仅基于发票加入两列的逻辑。 请让我知道如何加入,如果“年”在df1中是不可用的,数据帧应该加入的基础上“发票”。谢了。

  • 我的问题很简单,但我什么也找不到。 我有一个列表类和一个用于XML序列化的入口类: 我试图解析这个XML,它在列表中没有任何条目: 返回以下错误: 我做错了什么?元素列表设置为空=真,必需=假。有人能帮忙吗?

  • 问题内容: 我有以下代码来获取地图: 如何打印带有重复键的消息“重复键”? 问题答案: 如何打印带有重复键的消息“重复键”? 使用当前代码,您将收到消息“重复键”,其中包含至少2个实例的列表,这些实例具有与对象相同的值,例如。 如何获得对应的密钥? 到目前为止,还无法获得相应的键,当前从合并功能中获得的实际上是与相同键映射的2个值,这些值需要合并以仅保留对应键的一个值。 您的问题是 Java 9

  • 我正在尝试创建一个列表,列出在FTP服务器上的文件夹中找到的所有文件名。完整目录与登录凭据一起保存在设置数据库表中。它连接到FTP区域很好,我可以上传/下载文件。 这是我从文件夹中获取文件的代码。 我遇到的问题是,当前我试图搜索的文件夹是空的,但它找到了2个文件。 为什么会这样? 中的值是 这是我在FileZilla中打开它时的文件夹-它肯定是一个空文件夹。 如何查看系统文件中的所有文件并将其放入

  • 我使用的是volley.jar,在编译时没有错误,但是有运行时异常。 然后添加volley.jar和build path。什么是问题? CustomAdapter.java