java - 使用流和收集器创建嵌套映射

标签 java java-8 hashmap java-stream collectors

class QuizAnswers {
  List<MultipleChoiceAnswer> multipleChoiceAnswers;
  List<FreeResponseAnswer> freeResponseAnswers; //not relevant to this question
}

class MultipleChoiceAnswer {
  int questionId;
  // The index of the selected multiple choice question
  int answer_selection;
}

我的函数的输入是 List<QuizAnswers> .

我想创建 Map<Integer, Map<Integer, Long>> 的输出映射<MultipleChoiceAnswer.questionId : <MultipleChoiceAnswer.answer_selection, total count of answer_selection> 。换句话说,我想创建一个嵌套映射,将每个多项选择测验问题映射到表示该测验问题的每个答案选项的选择总数的映射。

假设输入List<QuizAnswers> quizAnswersList如:

[ {questionId: 1, answer_selection: 2},    
  {questionId: 1, answer_selection:2},  
  {questionId: 1, answer_selection:3},   
  {questionId: 2, answer_selection:1} ]

然后我希望输出是:

{1 : {2:2, 3:1}, 2: {1, 1}}

因为 Id = 1 的问题收到两个关于答案选项的选择 21选择答案选项 3而问题是 Id=21选择答案选项 1 .

我已经尝试过

quizAnswersList.stream()
            .map(
                quizAnswers ->
                    quizAnswers.getMultipleChoiceAnswers().stream()
                        .collect(
                            Collectors.groupingBy(
                                MultipleChoiceAnswer::getQuestionId,
                                Collectors.groupingBy(
                                    MultipleChoiceAnswer::getAnswerSelection,
                                    Collectors.counting()))));

这给了我一个错误。一般来说,我对流和收集器不太熟悉,所以我很想学习如何正确地做到这一点。

最佳答案

I want to create an output of Map<Integer, Map<Integer, Long>> that maps <MultipleChoiceAnswer.questionId : <MultipleChoiceAnswer.answer_selection>, total count of answer_selection>.

你很接近。你只是没有flatMap MultipleChoiceAnswers到流中,因此您有一个嵌套流,这导致了问题。

根据您编辑的问题,这是我的想法。

List<MultipleChoiceAnswer> mca =
        List.of(new MultipleChoiceAnswer(1, 2),
                new MultipleChoiceAnswer(1, 2),
                new MultipleChoiceAnswer(1, 3),
                new MultipleChoiceAnswer(2, 1));

// more could be added to the List.  You only provided one.
List<QuizAnswers> list = List.of(new QuizAnswers(mca));
  • flatMap 全部 MultipleChoice列表
  • questionId 将它们分组
  • 然后根据 AnswerSelection 对它们进行分组并得到一个计数
  • 然后您将获得您请求的 map 输出。
Map<Integer,Map<Integer,Long>> map = list.stream()
        .flatMap(s -> s.getMultipleChoiceAnswers().stream())
        .collect(Collectors.groupingBy(
                MultipleChoiceAnswer::getQuestionId,
                Collectors.groupingBy(
                        MultipleChoiceAnswer::getAnswerSelection,
                        Collectors.counting())));

map.entrySet().forEach(System.out::println);

打印

1={2=2, 3=1}
2={1=1}

问题

  • 您想如何处理多个QuizAnswer实例?
  • 您想如何处理多个 MulitpleChoiceAnswer列表。您只提供了其中一项。

它们都可能是flatmapped一起并按上述方式进行处理。但我认为答案可能存在一些差异(可能针对不同的测试),您不希望将其分组并计为相同。

示例

如果我将以下内容添加到 List<QuizAnswers>

List<MultipleChoiceAnswer> mca2 =
List.of(new MultipleChoiceAnswer(1, 2),
        new MultipleChoiceAnswer(1, 2),
        new MultipleChoiceAnswer(5, 2),
        new MultipleChoiceAnswer(5, 2));

使用上述解决方案进行处理,输出将是

1={2=4, 3=1}
2={1=1}
5={2=2}

关于java - 使用流和收集器创建嵌套映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71918958/

相关文章:

java - 将参数从 JavaScript (jQuery) 传送到基于 Java 的 REST 服务的最佳实践?

java8 lambda 带条件分组

java - 每个有状态的中间 Stream API 操作都保证一个新的源集合吗?

java - 是否可以为 HashMap 集创建队列?

Java - Hashmap检索序列

java - JMockit - 期望与 MockUp<T> 为什么一个有效而另一个无效?

java - Photoshop "Pucker Tool"算法

java - 为什么 SimpleDateFormat::format(Long) 适用于 Java?

java - 在 Map<String, Map<String, Double>> JSP 中通过键获取值

Java 项目文档