如何使用Java流对子列表中的元素进行分组和计数

时间:2019-03-04 17:16:48

标签: java java-stream grouping counting

我想使用Java流对子列表中的元素进行分组和计数。

例如,我有一个类型为AnswerWithOneCorrectOption的答案,如下所示:

class AnswerWithOneCorrectOption {
     Long choiceId;
}

此答案类型只有一个正确的选项,并存储在“ AnswerWithOneCorrectOption.id”中。我正在遍历AnswerWithOneCorrectOption的列表,根据ID进行分组并使用:

private Map<Long, Long> countChoicesAndGroup(List<AnswerWithOneCorrectOption> answers){

Map<Long, Long> map = answers.parallelStream()
             .collect(Collectors.groupingBy(AnswerWithOneCorrectOption::getChoiceId, 
 Collectors.counting())); 

 return map;
}

假设我有另一种答案类型,可以有多个正确的选项。我将这些选项保存在List<Long> choiceIds中。

class AnswerWithMultipleCorrectOptions {
     List<Long> choiceIds;
}

如何按List<Long> choiceIds中的choiceId进行分组并计数?

1 个答案:

答案 0 :(得分:1)

  

如果用户仅选择一个选项,它将保存在answer.id中。如果他选择了多个答案,我会将其添加到列表answer.ids中。

最好将AnswerList<Long> ids一起使用。如果用户只选择了一个选项,则只包含一个元素的列表。这允许您通过两种情况的答案分组(不要忘记equals / hashcode):

Map<Answer, Long> collect = answers.stream()
        .collect(groupingBy(Function.identity(), counting()));

但是,如果您想按List<Long>分组,可以用相同的方法完成:

Map<List<Long>, Long> collect = answers.stream()
            .collect(groupingBy(Answer::choiceIds, counting()));

更新:要对子列表中的元素进行分组,您可以在之前使用flatMap

Map<Long, Long> map = answers.stream()
        .flatMap(answer -> answer.getIds().stream())
        .collect(groupingBy(Function.identity(), counting()));