用Java实现pivot表

用Java实现pivot表,java,collections,group-by,pivot,java-stream,Java,Collections,Group By,Pivot,Java Stream,我需要用Java实现一个透视表,我知道如何使用Java8流特性。网络上有很多很好的解决方案,但我需要更多的东西,我不知道如何做到这一点:我需要创建一个更动态的表,理想情况下,您不知道要聚合哪些列。 例如,如果我有列(“国家”、“公司”、“行业”、“雇员人数”),我必须输入: 度量值的自定义聚合函数(例如sum) 一个可变的聚合顺序:例如,我想要第一个聚合,作为参数“Nation”或者作为参数“Nation”和“Company”,我作为参数给出了类似“Nation->Company”的内容。 换

我需要用Java实现一个透视表,我知道如何使用Java8流特性。网络上有很多很好的解决方案,但我需要更多的东西,我不知道如何做到这一点:我需要创建一个更动态的表,理想情况下,您不知道要聚合哪些列。 例如,如果我有列(“国家”、“公司”、“行业”、“雇员人数”),我必须输入:

  • 度量值的自定义聚合函数(例如sum)
  • 一个可变的聚合顺序:例如,我想要第一个聚合,作为参数“Nation”或者作为参数“Nation”和“Company”,我作为参数给出了类似“Nation->Company”的内容。 换句话说,我不知道聚合的字段是什么,基本上我需要一种方法来实现一个通用的GROUPBY SQL子句,比如:
//给定一个数组列表(“国家”、“公司”、“行业”、“雇员人数”)调用带有一些行的数据
Map Map=data.stream().collect(
Collectors.groupingBy(行->行[0]。toString()+“-”+行[1]。toString());
对于(Map.Entry:Map.entrySet()){
最终双平均值=entry.getValue().stream()
.mapToInt(row->(int)row[3]).average().getAsDouble();
这不是我需要的,因为它太明确了

我需要:

  • 按从数据中提取的标题名(或更多,取决于我必须按多少列进行分组)给定的值拆分子列表中的输入Arraylist
  • 聚合每个子列表
  • 联合子列表
有人能帮我吗?谢谢你导入java.util.array;
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);
    }
}
导入java.util.List; 导入java.util.Map; 导入java.util.function.function; 导入java.util.stream.collector; 类输入{ 私人串国家、公司、行业; 私人雇员; 公共输入(字符串国家、字符串公司、字符串行业、整数员工){ 超级(); 这个国家=国家; 这个公司=公司; 这个。工业=工业; 这是。雇员=雇员; } 公共字符串getNation(){ 回归国家; } 公共无效设置(字符串国家){ 这个国家=国家; } 公共字符串getCompany(){ 返回公司; } 上市公司(字符串公司){ 这个公司=公司; } 公共字符串getIndustry(){ 回归产业; } 公共行业(字符串行业){ 这个。工业=工业; } public int getEmployees(){ 返回员工; } 公共雇员(内部雇员){ 这是。雇员=雇员; } @凌驾 公共字符串toString(){ 返回字符串格式( “国家:%s,公司:%s,行业:%s,员工:%s”, 国家、公司、行业、员工); } } 公共类CustomGroupBy{ //通用群比 静态映射groupBy(列表输入, 函数分类器){ 返回input.stream().collect(收集器.groupingBy(分类器)); } 公共静态void main(字符串[]args){ 列表输入=Arrays.asList(新输入(“印度”、“A”、“IT”12), 新输入(“美国”、“B”、“电气”,90),新输入(“印度”, “B”,“机械”,122),新输入(“印度”,“B”,“IT”, 12) ,新输入(“印度”、“C”、“IT”、200”); //您需要传入此参数 函数groupByFun=i->i.getNation()+“-” +i.获得公司(); //示例-1 Map groupBy=groupBy(输入,输入::getCompany); //示例2 Map groupBy2=groupBy(输入,groupByFun); System.out.println(groupBy2); 列表平均值=groupBy .entrySet() .stream() .map(entry->entry.getValue().stream()) .mapToInt(行->行.getEmployees()).average() .getAsDouble()).collect(收集器.toList()); 系统输出打印项次(平均值); } } 您可以通过传递函数接口使其通用。仅供参考。

import java.util.Arrays;
导入java.util.List;
导入java.util.Map;
导入java.util.function.function;
导入java.util.stream.collector;
类输入{
私人串国家、公司、行业;
私人雇员;
公共输入(字符串国家、字符串公司、字符串行业、整数员工){
超级();
这个国家=国家;
这个公司=公司;
这个。工业=工业;
这是。雇员=雇员;
}
公共字符串getNation(){
回归国家;
}
公共无效设置(字符串国家){
这个国家=国家;
}
公共字符串getCompany(){
返回公司;
}
上市公司(字符串公司){
这个公司=公司;
}
公共字符串getIndustry(){
回归产业;
}
公共行业(字符串行业){
这个。工业=工业;
}
public int getEmployees(){
返回员工;
}
公共雇员(内部雇员){
这是。雇员=雇员;
}
@凌驾
公共字符串toString(){
返回字符串格式(
“国家:%s,公司:%s,行业:%s,员工:%s”,
国家、公司、行业、员工);
}
}
公共类CustomGroupBy{
//通用群比
静态映射groupBy(列表输入,
函数分类器){
返回input.stream().collect(收集器.groupingBy(分类器));
}
公共静态void main(字符串[]args){
列表输入=Arrays.asList(新输入(“印度”、“A”、“IT”12),
新输入(“美国”、“B”、“电气”,90),新输入(“印度”,
“B”,“机械”,122),新输入(“印度”,“B”,“IT”
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);
    }
}
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

class Scratch {
    // Input class from Anant Goswami in previous reply
    static 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 Object get(String field){
            switch (field.toLowerCase()){
                case "nation": return getNation();
                case "company": return getCompany();
                case "industry": return getIndustry();
                case "employees": return getEmployees();
                default: throw new UnsupportedOperationException();
            }
        }
    }

    private static Map<String, List<Input>> group(List<Input> inputs, String... fields){
        Function<Input, String> groupBy = i -> Arrays.stream(fields).map(f -> i.get(f).toString()).collect(Collectors.joining("-"));
        Map<String, List<Input>> result = inputs.stream().collect(Collectors.groupingBy(groupBy));
        System.out.println(result);
        return result;
    }

    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));
        group(input, "company");
        group(input, "nation", "Company");
    }
}
{A=[Nation : India, Company : A, Industry : IT, Employees : 12], B=[Nation : USA, Company : B, Industry : ELECTRICAL, Employees : 90, Nation : India, Company : B, Industry : MECHANICAL, Employees : 122, Nation : India, Company : B, Industry : IT, Employees : 12], C=[Nation : India, Company : C, Industry : IT, Employees : 200]}
{India-B=[Nation : India, Company : B, Industry : MECHANICAL, Employees : 122, Nation : India, Company : B, Industry : IT, Employees : 12], India-C=[Nation : India, Company : C, Industry : IT, Employees : 200], India-A=[Nation : India, Company : A, Industry : IT, Employees : 12], USA-B=[Nation : USA, Company : B, Industry : ELECTRICAL, Employees : 90]}