我有一个ArrayList<Map<String, Object>>像数据库表这样的数据.我想用自己的Java来计算Subtotal总成员数.GroupBY Rollup/Cube可以在SQL中实现相同的功能.我写了一个函数来计算GroupBy Cube.
public static List<Map<String, Object>> applyGroupBy(List<LevelDetail> dimensionColumns, List<MeasureDetail> numericColumns, List<Map<String, Object>> resultset) {
List<Map<String, Object>> resultsetNew = new ArrayList<Map<String, Object>>();
Map<String, List<Double>> grandTotalMap = new HashMap<String, List<Double>>();
for (LevelDetail levelDetail : dimensionColumns) {
Stream<Map<String, Object>> stream = resultset.stream();
stream.collect(Collectors.groupingBy(m -> m.get(levelDetail.getName()), LinkedHashMap::new, Collectors.mapping(m -> m, Collectors.toList()))).forEach((g, r) -> {
Map<String, Object> row = new HashMap<String, Object>();
row.put(levelDetail.getName(), g);
for (MeasureDetail measureDetail : numericColumns) {
DoubleStream valueStream = r.stream().mapToDouble(p -> {
p.put(levelDetail.getName() + "_nb_grouping", 0);
resultsetNew.add(p);
return Double.parseDouble(p.get(measureDetail.getName()) != null ? p.get(measureDetail.getName()).toString() : "0");
});
Double value = getAggregatedResult(valueStream, measureDetail.getMeasure_rollup_expr());
row.put(measureDetail.getName(), value);
if (dimensionColumns.indexOf(levelDetail) == 0) {
if (!grandTotalMap.containsKey(measureDetail.getName())) {
grandTotalMap.put(measureDetail.getName(), new ArrayList<Double>());
}
grandTotalMap.get(measureDetail.getName()).add(value);
}
}
row.put(levelDetail.getName() + "_nb_grouping", 0);
for (LevelDetail ld : dimensionColumns) {
if (!ld.getName().equals(levelDetail.getName())) {
row.put(ld.getName() + "_nb_grouping", 1);
row.put(ld.getName(), null);
}
}
resultsetNew.add(row);
});
}
Map<String, Object> row = new HashMap<String, Object>();
for (LevelDetail levelDetail : dimensionColumns) {
row.put(levelDetail.getName(), null);
row.put(levelDetail.getName() + "_nb_grouping", 1);
}
for (MeasureDetail measureDetail : numericColumns) {
Double value = getAggregatedResult(grandTotalMap.get(measureDetail.getName()).stream().mapToDouble((i) -> (Double) i), measureDetail.getMeasure_rollup_expr());
row.put(measureDetail.getName(), value);
}
resultsetNew.add(row);
resultset = new ArrayList<Map<String, Object>>(new LinkedHashSet<Map<String, Object>>(resultsetNew));
resultsetNew.clear();
resultsetNew.addAll(resultset);
return resultsetNew;
}
private static final String AVG = "avg";
private static final String MIN = "min";
private static final String MAX = "max";
private static Double getAggregatedResult(DoubleStream ds, String agg) {
switch (agg.toLowerCase()) {
case AVG:
return ds.average().getAsDouble();
case MIN:
ds.min().getAsDouble();
case MAX:
ds.max().getAsDouble();
default:
return ds.sum();
}
}
Run Code Online (Sandbox Code Playgroud)
我想写一个由Rollup分组的方法.无论是按Rollup还是Cube分组,它都可以参数化为相同的函数.
当使用不如商业软件强大的自由软件 SGBD 时,有时必须在 Java 代码中实现某些功能。汇总似乎是多维数据集查询的子集。因此,要获得汇总,您必须从多维数据集查询中删除一些行以及一些部分总计。在具体情况下,这可能相当容易,但概括起来可能需要一些时间才能准确地发现应该删除哪些行以及在每种情况下哪种算法可以执行它。
| 归档时间: |
|
| 查看次数: |
790 次 |
| 最近记录: |