我有一个包含数据( 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并同时计算更改?
答案 0 :(得分:3)
杰里米·格兰德在评论中完全正确:在你的收藏家中,人们早已忘记你是从一群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
。
这不是最漂亮的流代码,我会等着看是否有其他建议。
代码已编译,但由于我既没有您的类也没有您的数据,我没有尝试过运行它。如果有任何问题,请恢复。
答案 1 :(得分:0)
你的错误是Commit
号召“扔掉”Commit
。尝试收集时,您不知道Change
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
。为了保留这些信息,我建议创建一个小帮助类(你可以使用一个简单的对):
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.counting()
,请将@Html.DropDownListFor(model => model.Product,
new SelectList(Model.ProductsList, "Key", "Value"), "-- Product --",
new { @class = "form-control" } )
替换为@Html.DropDownListFor(model => model.Product,
new SelectList(Model.ProductsList), "-- Product --",
new { @class = "form-control" } )
。