Home > Java > body text

Java 8 stream group by 3 fields and aggregate other two fields by sum

PHPz
Release: 2024-02-22 13:46:06
forward
960 people have browsed it

php editor Strawberry brings you questions and answers about grouping streams by 3 fields and aggregating the other two fields by the sum in Java 8. In Java programming, streams are a new way of processing collections. By using streams, data can be manipulated and processed more conveniently. This article will introduce in detail how to use the stream function of Java 8 to group by 3 fields and perform sum aggregation on the other two fields. Let’s explore this interesting question together!

Question content

I am new to java 8 and am having difficulty implementing the solutions that have been provided on similar questions. please help.

In java 8, how to group by three fields that returns multiple rows that must be summed over the remaining two integer fields. In the dto/pojo class below, the incoming count and outgoing count fields need to be summed based on the unique key of the uuid, msgdate, and channel combination.

public class reportdata {

    private string uuid;
    private string msgdate;
    private string channel;
    private integer incomingcount;
    private integer outgoingcount;
}
Copy after login

//Initialization list as an example.

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 ));
Copy after login

The output object should contain the following data:

uuid msgdate Channel incoming count outgoing count

c9c3a519 December 2023 Number 8 3

c9c3a519 November 2023 Number 4 4

c9c3a519 December 2023 Manual 8 3

c9c3a519 November 2023 Manual 4 4

...

...

...

Solution

Collect the results into a map. This example will use Collectors.toMap(keyMapper, valueMapper, mergeFunction, mapFactory).

Also, for the sake of brevity, I use lombok annotations.

First create classes to represent the keys and aggregated data to be grouped:

@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;
  }
}
Copy after login
@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;
  }
}
Copy after login

Then extend reportdata with 2 more methods to create the key and initial aggregation:

@allargsconstructor
public class reportdata {

  //the fields

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

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

and collect data:

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());
    }
  }
}
Copy after login

The parameters of the collector are as follows:

  1. reportdata::createkey - Create the key to group by (key of the map)
  2. reportdata::createcount - Creates an initial aggregate from a single reportdata
  3. (the value of the map)
  4. count::merge - Merge two count (see merge method)
  5. when a key conflict occurs
  6. linkedhashmap::new - Factory for map used to insert results. I want to preserve the insertion order, but if not needed, the parameter can be omitted to use the default factory.

Print:

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
Copy after login

The above is the detailed content of Java 8 stream group by 3 fields and aggregate other two fields by sum. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!