java - Java 8 中超过 2 个 groupingBy 操作

标签 java java-8 java-stream grouping

这是我的“revenue_data.csv”文件:

Client  ReportDate  Revenue
C1      2019-1-7    12
C2      2019-1-7    34
C1      2019-1-16   56
C2      2019-1-16   78
C3      2019-1-16   90

我读取文件的案例类是:

package com.source.code;

import java.time.LocalDate;

public class RevenueRecorder {

    private String clientCode;
    private LocalDate reportDate;
    private int revenue;


    public RevenueRecorder(String clientCode, LocalDate reportDate, int revenue) {
        this.clientCode = clientCode;
        this.reportDate = reportDate;
        this.revenue = revenue;
    }

    public String getClientCode() {
        return clientCode;
    }

    public LocalDate getReportDate() {
        return reportDate;
    }

    public int getRevenue() {
        return revenue;
    }
}

我可以通过以下方式读取文件并按 ReportDate、sum(revenue) 进行分组:

import com.source.code.RevenueRecorder;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingInt;

public class RevenueRecorderMain {

    public static void main(String[] args) throws IOException {

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");
        List<RevenueRecorder> revenueRecords = new ArrayList<>();

        Path path = FileSystems.getDefault().getPath("src", "main", "resources",
                "data", "revenue_data.csv");

        Files.lines(path)
                .skip(1)
                .map(s -> s.split(","))
                .forEach(s ->
                {
                    String clientCode = s[0];
                    LocalDate reportDate = LocalDate.parse(s[1], formatter);
                    int revenue = Integer.parseInt(s[2]);

                    revenueRecords.add(new RevenueRecorder(clientCode, reportDate, revenue));

                });

        Map<LocalDate, Integer> reportDateRev = revenueRecords.stream()
                .collect(groupingBy(RevenueRecorder::getReportDate,
                        summingInt(RevenueRecorder::getRevenue)));
    }
}

我的问题是如何在 Java 8 中按 ReportDate、count(clientCode) 和 sum(revenue) 进行分组,具体来说:

  • 使用什么集合来代替 map
  • 在这种情况下如何进行分组和收集(通常对于 2 个以上的分组)

我正在尝试:

//import org.apache.commons.lang3.tuple.ImmutablePair;
//import org.apache.commons.lang3.tuple.Pair;

        Map<LocalDate, Pair<Integer, Integer>> pairedReportDateRev = revenueRecords.stream()
                .collect(groupingBy(RevenueRecorder::getReportDate,
                        new ImmutablePair(summingInt(RevenueRecorder::getRevenue),
                        groupingBy(RevenueRecorder::getClientCode, Collectors.counting()))));

但是使用悬停消息“无法从静态上下文引用非静态方法”在 RevenueRecorder::getReportDate 下获取 Intellij 红色曲线。

谢谢

编辑 为了澄清起见,下面是我试图获取的相应 SQL 查询:

select 
    reportDate, count(distinct(clientCode)), sum(revenue)
from
    revenue_data_table
group by
    reportDate

最佳答案

虽然你的尝试没有成功,但我想这是你最想表达的。所以我只是按照你的代码并修复它。试试这个!

Map<LocalDate, ImmutablePair<Integer, Map<String, Long>>> map = revenueRecords.stream()
            .collect(groupingBy(RevenueRecorder::getReportDate,
                    collectingAndThen(toList(), list -> new ImmutablePair(list.stream().collect(summingInt(RevenueRecorder::getRevenue)),
                                                                          list.stream().collect(groupingBy(RevenueRecorder::getClientCode, Collectors.counting()))))));

我从@Lyashko Kirill借用了一些示例数据代码来测试我的代码,结果如下 enter image description here

这是我自己的想法,希望能帮到你。 ╰( ̄▽ ̄)╭

关于java - Java 8 中超过 2 个 groupingBy 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57689948/

相关文章:

Java 8 Date API - 获取一个月的总周数

java - 在 Java 8 中是否有一种简洁的方法来迭代带有索引的流?

java - 将 forEachOrdered 与并行流一起使用的好处

java - 如果 Stream 没有结果则抛出异常

java - 输出问题,Java

java - 需要解决 Tomcat 在记录器被处理后尝试记录事件的 webapp 错误

java - 使用 API 和服务帐户创建的新日历不可见

java - 如何选择不同的字符串? (更轻松)

Java 8 流和简单类型

Java - 并行发送多封邮件