java - 在 Java 中实现数据透视表

标签 java collections group-by pivot java-stream

我需要在 Java 中实现数据透视表,并且我知道如何使用 Java 8 Streams 功能。网络上有很多好的解决方案,但我需要更多的东西,但我不明白如何做到这一点:我需要创建一个更动态的表,理想情况下您不知道必须聚合哪些列。 例如,如果我有列(“国家”、“公司”、“行业”、“员 worker 数”),我必须作为输入给出:

  • 度量的自定义聚合函数(例如 sum)
  • 聚合的可变顺序:例如,我想要国家的第一个聚合,我给出“国家”作为参数,或者国家和公司,我给出类似“国家->公司”的参数。 换句话说,我不知道哪些是我的聚合字段,基本上我需要一种方法来实现通用 GROUP BY SQL 子句,所以类似于:
// Given an the Arraylist ("Nation", "Company", "Industry","Number of employes") called data with some rows

Map<String, List<Object[]>> map = data.stream().collect(
                Collectors.groupingBy(row -> row[0].toString() + "-" + row[1].toString()));

for (Map.Entry<String, List<Object[]>> entry : map.entrySet()) {
            final double average = entry.getValue().stream()
                    .mapToInt(row -> (int) row[3]).average().getAsDouble();

这不是我需要的,因为它太明确了。

我需要:

  • 按照我从数据中提取的标题名称给出的值拆分子列表中的输入Arraylist(或更多,这取决于我必须分组的列数)
  • 聚合每个子列表
  • 合并子列表

有人可以帮助或激励我吗?谢谢

最佳答案

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

class Input {
    private String nation, company, industry;
    private int employees;

    public Input(String nation, String company, String industry, int employees) {
        super();
        this.nation = nation;
        this.company = company;
        this.industry = industry;
        this.employees = employees;
    }

    public String getNation() {
        return nation;
    }

    public void setNation(String nation) {
        this.nation = nation;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getIndustry() {
        return industry;
    }

    public void setIndustry(String industry) {
        this.industry = industry;
    }

    public int getEmployees() {
        return employees;
    }

    public void setEmployees(int employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {

        return String.format(
                "Nation : %s, Company : %s, Industry : %s, Employees : %s",
                nation, company, industry, employees);
    }
}

public class CustomGroupBy {

    // Generic GroupBy
    static Map<String, List<Input>> groupBy(List<Input> input,
            Function<Input, String> classifier) {
        return input.stream().collect(Collectors.groupingBy(classifier));
    }

    public static void main(String[] args) {

        List<Input> input = Arrays.asList(new Input("India", "A", "IT", 12),
                new Input("USA", "B", "ELECTRICAL", 90), new Input("India",
                        "B", "MECHANICAL", 122), new Input("India", "B", "IT",
                        12), new Input("India", "C", "IT", 200));

        // You need to pass this in parameter
        Function<Input, String> groupByFun = i -> i.getNation() + "-"
                + i.getCompany();

        // Example-1
        Map<String, List<Input>> groupBy = groupBy(input, Input::getCompany);

        // Example-2
        Map<String, List<Input>> groupBy2 = groupBy(input, groupByFun);

        System.out.println(groupBy2);

        List<Double> averages = groupBy
                .entrySet()
                .stream()
                .map(entry -> entry.getValue().stream()
                        .mapToInt(row -> row.getEmployees()).average()
                        .getAsDouble()).collect(Collectors.toList());
        System.out.println(averages);
    }
}

您可以通过传递函数接口(interface)使其通用。仅供您引用。

关于java - 在 Java 中实现数据透视表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55670483/

相关文章:

python - groupby 多个值列

java - 无法确定此 SQL 语句不执行的原因 (Derby)

java - 如何将文件从 Dos 转换为 Unix

java - 容量适配 Java 集合

Java 集合 ArrayList、LinkedList 抛出异常

mysql - 无法使用同一表上的内部联接从表中提取数据

mysql - 滞后函数中组函数的使用无效

java - 为什么 PDFBox PDFRenderer 很慢?

java - Java中如何解析方法引用

java - 按特定顺序对列表列表进行排序