如何使用Java 8流生成具有嵌套集合的摘要报告?

时间:2016-08-09 00:36:46

标签: java-8

我有一个像这样的类的对象列表:

class TestResult{
  int userId;
  Set<String> subjects; 
  int score;
}

我想为每个主题中的每个userId生成得分摘要

Map<String,Map<Integer, Integer>>

外部地图以主题为关键。内部地图将userId作为关键字,将得分之和作为值。

2 个答案:

答案 0 :(得分:0)

(请注意:在下文中,我将您(当前未命名的)课程称为MixedScores

让我们定义一个方法sumScores,该方法需要Collection<MixedScores>并返回按您要求编写的Map<String, Map<Integer, Integer>>

您可以使用本地类SingleScore来帮助在多个实例中拆分单个MixedScores实例,然后按主题,按userId对它们进行分组,最后总结所有找到的分数。

在代码中:

Map<String, Map<Integer, Integer>> sumScores(Collection<MixedScores> scores) {
    class SingleScore {
        int userId;
        String subject;
        int score;

        SingleScore(MixedScores mixedScores, String subject) {
            this.userId = mixedScores.userId;
            this.subject = subject;
            this.score = mixedScores.score;
        }

        String getSubject() {
            return subject;
        }

        int getUserId() {
            return userId;
        }

        int getScore() {
            return score;
        }
    }

    return scores.stream()
            .flatMap(x -> x.subjects.stream().map(subject -> new SingleScore(x, subject)))
            .collect(groupingBy(SingleScore::getSubject,
                    groupingBy(SingleScore::getUserId, summingInt(SingleScore::getScore))));
}

当然,有一些进口:

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

这对你有用吗?

答案 1 :(得分:0)

另一种不创建新类的方法,由@Flown

建议
                scores.stream()
                    .flatMap(x -> x.subjects.stream()
                            .map(subject -> new AbstractMap.SimpleEntry<String, Entry<Integer, Integer>>(subject,
                                    new AbstractMap.SimpleEntry<Integer, Integer>(x.userId, x.score))))
                    .collect(Collectors.groupingBy(Entry<String, Entry<Integer, Integer>>::getKey,
                            Collectors.groupingBy(p -> p.getValue().getKey(),
                                    Collectors.summingInt((p -> p.getValue().getValue())))));