簡體   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