首頁  >  文章  >  Java 8流以3個字段分組並按總和聚合其他兩個字段

Java 8流以3個字段分組並按總和聚合其他兩個字段

PHPz
PHPz轉載
2024-02-22 13:46:06961瀏覽

php小編草莓為您帶來Java 8中流按3個字段分組並按總和聚合其他兩個字段的問答。在Java程式設計中,流是一種新的處理集合的方式,透過使用流可以更方便地對資料進行操作和處理。本文將詳細介紹如何使用Java 8的流程功能來實現依照3個欄位進行分組,並對其他兩個欄位進行總和聚合的操作。讓我們一起來探索這個有趣的問題吧!

問題內容

我是 java 8 的新手,在實作類似問題上已提供的解決方案時遇到了困難。請幫忙。

在 java 8 中,如何對三個欄位進行分組,該欄位傳回多個行,這些行必須對其餘兩個整數欄位進行求和。 在下面的 dto/pojo 類別中,需要根據 uuid、msgdate 和通道組合的唯一鍵對傳入計數和傳出計數欄位進行求和。

public class reportdata {

    private string uuid;
    private string msgdate;
    private string channel;
    private integer incomingcount;
    private integer outgoingcount;
}

//初始化清單作為範例。

List<ReportData> list1 = new ArrayList<>();

list1.add(new ReportData("c9c3a519","December 2023", "digital", 5, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "digital", 3, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "digital", 0, 3 ));
list1.add(new ReportData("c9c3a519","November 2023", "digital", 4, 0 ));
list1.add(new ReportData("c9c3a519","November 2023", "digital", 0, 4 ));
list1.add(new ReportData("c9c3a519","December 2023", "manual", 5, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "manual", 3, 0 ));
list1.add(new ReportData("c9c3a519","December 2023", "manual", 0, 3 ));
list1.add(new ReportData("c9c3a519","November 2023", "manual", 4, 0 ));
list1.add(new ReportData("c9c3a519","November 2023", "manual", 0, 4 ));
list1.add(new ReportData("3de4c44f","December 2023", "digital", 5, 0 ));
list1.add(new ReportData("3de4c44f","December 2023", "digital", 0, 3 ));
list1.add(new ReportData("3de4c44f","November 2023", "digital", 4, 0 ));
list1.add(new ReportData("3de4c44f","November 2023", "digital", 0, 4 ));
list1.add(new ReportData("3de4c44f","December 2023", "manual", 5, 0 ));
list1.add(new ReportData("3de4c44f","December 2023", "manual", 0, 3 ));
list1.add(new ReportData("3de4c44f","November 2023", "manual", 4, 0 ));
list1.add(new ReportData("3de4c44f","November 2023", "manual", 0, 4 ));

輸出物件應包含以下資料:

uuid msgdate 通道傳入計數傳出計數

#c9c3a519 2023 年 12 月數字 8 3

# c9c3a519 2023 年 11 月數字 4 4

c9c3a519 2023 年 12 月手冊 8 3

c9c3a519 2023 年 11 月手冊 4 4

...

...

...

解決方法

將結果收集到地圖中。此範例將使用 Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapFactory)

此外,為了簡潔起見,我使用 lombok 註解。

先建立類別來表示要分組的鍵和聚合資料:

@allargsconstructor
@getter
public class count {

  private final int in;
  private final int out;

  public count merge(count other) {
    return new count(this.in + other.in, this.out + other.out);
  }

  @override
  public string tostring() {
    return in + " " + out;
  }
}
@allargsconstructor
public class key {

  private final string uuid;
  private final string date;
  private final string channel;

  @override
  public int hashcode() {
    return objects.hash(uuid, date, channel);
  }

  @override
  public boolean equals(object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof key)) {
      return false;
    }
    key other = (key) obj;
    return uuid.equals(other.uuid) && date.equals(other.date) && channel.equals(other.channel);
  }

  @override
  public string tostring() {
    return uuid + " " + date + " " + channel;
  }
}

然後使用另外 2 個方法擴充 reportdata 來建立金鑰和初始聚合:

@allargsconstructor
public class reportdata {

  //the fields

  public key createkey() {
    return new key(uuid, msgdate, channel);
  }

  public count createcount() {
    return new count(incomingcount, outgoingcount);
  }
}

並收集資料:

public class somain {

  public static void main(string[] args) {
    list<reportdata> list = new arraylist<>();

    //populate the list

    map<key, count> result = list.stream()
            .collect(collectors.tomap(reportdata::createkey, reportdata::createcount, count::merge, linkedhashmap::new));
    for (map.entry<key, count> entry : result.entryset()) {
      system.out.println(entry.getkey() + " " + entry.getvalue());
    }
  }
}

收集器的參數如下:

  1. reportdata::createkey - 建立分組依據的鍵(地圖的鍵)
  2. reportdata::createcount - 從單一 reportdata(地圖的值)建立初始聚合
  3. count::merge - 在按鍵衝突時合併兩個 count(請參閱合併方法)
  4. linkedhashmap::new - 用於插入結果的 map 的工廠。我想保留插入順序,但如果不需要,可以省略該參數以使用預設工廠。

列印:

c9c3a519 December 2023 digital 8 3
c9c3a519 November 2023 digital 4 4
c9c3a519 December 2023 manual 8 3
c9c3a519 November 2023 manual 4 4
3de4c44f December 2023 digital 5 3
3de4c44f November 2023 digital 4 4
3de4c44f December 2023 manual 5 3
3de4c44f November 2023 manual 4 4

以上是Java 8流以3個字段分組並按總和聚合其他兩個字段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除