繁体   English   中英

填写地图 <String,Map<String,Integer> &gt;与流

[英]Fill Map<String,Map<String,Integer>> with Stream

我有一个带有数据的( author, date , LinkedList<Changes(lines, path)> )

现在我想用这个流创建一个Map< Filepath, Map< Author, changes >>

public Map<String, Map<String, Integer>> authorFragmentation(List<Commit> commits) {

        return commits.stream()
                      .map(Commit::getChangesList)
                      .flatMap(changes -> changes.stream())
                      .collect(Collectors.toMap(
                              Changes::getPath,
                              Collectors.toMap(
                                 Commit::getAuthorName, 
                                 (changes) -> 1,
                                 (oldValue, newValue) -> oldValue + 1)));
}

我这样尝试,但这行不通。 如何在带有Stream的Map中创建此Map并同时计算更改?

杰里米·格兰德(Jeremy Grand)的评论完全正确:在收藏家中,人们早就忘记了您是从Commit对象流开始的,因此您不能在其中使用Commit::getAuthorName 面临的挑战是如何将作者姓名保留在您也可以找到路径的地方。 一种解决方案是将两者都放入新创建的字符串数组中(因为两者都是字符串)。

public Map<String, Map<String, Long>> authorFragmentation(List<Commit> commits) {
    return commits.stream()
            .flatMap(c -> c.getChangesList()
                    .stream()
                    .map((Changes ch) -> new String[] { c.getAuthorName(), ch.getPath() }))
            .collect(Collectors.groupingBy(sa -> sa[1], 
                    Collectors.groupingBy(sa -> sa[0], Collectors.counting())));
}

Collectors.counting()坚持要计数为Long而不是Integer ,因此我修改了您的返回类型。 我敢肯定,如有必要,可以转换为Integer ,但是我首先考虑是否可以和Long住。

这不是最漂亮的流代码,我将等待看看是否有其他建议。

该代码已编译,但是由于我既没有您的类也没有您的数据,所以我没有尝试运行它。 如果有任何问题,请还原。

您的错误是map/flatMap调用“丢弃”了Commit 尝试收集时,您不知道哪个Change属于哪个Commit Change 为了保留这些信息,我建议创建一个小的帮助程序类(不过,您可以使用一个简单的Pair):

public class OneChange
{
    private Commit commit;
    private Change change;

    public OneChange(Commit commit, Change change)
    {
        this.commit = commit;
        this.change = change;
    }

    public String getAuthorName() { return commit.getAuthorName(); };
    public String getPath()       { return change.getPath(); };
    public Integer getLines()     { return change.getLines(); };
}

然后,您可以将flatMap设置为该flatMap ,按路径和作者对其进行分组,然后汇总更改的行:

commits.stream()
       .flatMap(commit -> commit.getChanges().stream().map(change -> new OneChange(commit, change)))
       .collect(Collectors.groupingBy(OneChange::getPath,
                                      Collectors.groupingBy(OneChange::getAuthorName,
                                                            Collectors.summingInt(OneChange::getLines))));

如果您不想汇总行数,而只是计算Changes ,请用Collectors.summingInt(OneChange::getLines)替换Collectors.summingInt(OneChange::getLines) Collectors.counting()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM