[英]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.