java - 在 Java 中实现数据透视表
问题描述
我需要用 Java 实现一个数据透视表,并且我知道如何使用 Java 8 Streams 功能。网上有很多很好的解决方案,但我需要更多的东西,但我不明白该怎么做:我需要创建一个更动态的表,理想情况下你不知道你必须聚合哪些列。例如,如果我有列(“国家”、“公司”、“行业”、“雇员人数”),我必须输入:
- 度量的自定义聚合函数(例如 sum)
- 聚合的可变顺序:例如,我想要 Nation 的第一个聚合,我将其作为参数“Nation”或 Nation 和 Company,并且我将其作为参数,例如“Nation->Company”。换句话说,我不知道哪些是我的聚合字段,基本上我需要一种方法来实现一个通用的 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);
}
}
您可以通过传递功能接口使其通用。仅供您参考。
推荐阅读
- reactjs - React+Typescript 冲突中的 createContext
- python - 在 pycaret 中使用 tune_model() 时,有没有办法查看所有尝试过的模型的指标和超参数?
- angular - 如果语句没有以角度显示 div 中的元素?
- pysimplegui - 在 Jupyter 上运行 PySimpleGUI
- pine-script - RSI 松树脚本
- java - Amazon Linux AMI 上的“bash: jstack: command not found”错误
- python - Scipy UnivariateSpline 崩溃
- python - NoneType 实际上是什么意思?
- javascript - 如何向客户端发送响应并将响应放入客户端的变量中(快递)
- php - ESP8266 到 000webhost 没有获取数据一个 php 文件