使用Java流API来汇总SQL GROUP BY之类的数据

Bru*_*uce 7 java sum java-stream

使用SQL我可以写这个来汇总数据:

SELECT sum(f1), sum(f2), f3, f4 FROM TABLEX GROUP BY f3, f4
Run Code Online (Sandbox Code Playgroud)

这将返回一个列表,每行包含4个值:sum1,sum2,v3,v4

例如:这是表中的内容:

1, 2, a, b
1, 2, a, b
2, 2, c, d
2, 2, c, d
3, 4, c, d
Run Code Online (Sandbox Code Playgroud)

结果将是:

2, 4, a, b
7, 8, c, d
Run Code Online (Sandbox Code Playgroud)

现在假设我没有数据库表,而是在具有变量f1,f2,f3,f4的Java对象列表中有数据.Java流API中是否有一个函数可以根据f3,f4汇总这个列表?

MCh*_*ker 2

正如OP所说:

f1,f2是双值。f3,f4可以是任何东西。

那么让我们考虑一下这个类:

public class TABLEX {
   double f1;
   double f2;
   Object f3;
   Object f4;
   //getters and setters
}
Run Code Online (Sandbox Code Playgroud)

列表示例TABLEX

List<TABLEX> list = new ArrayList<TABLEX>();
list.add(new TABLEX(1, 2, "a", "b"));
list.add(new TABLEX(1, 2, "a", "b"));
list.add(new TABLEX(2, 2, "c", "d"));
list.add(new TABLEX(2, 2, "c", "d"));
list.add(new TABLEX(3, 4, "c", "d"));
Run Code Online (Sandbox Code Playgroud)

相当于SELECT sum(f1) FROM TABLEX GROUP BY f3, f4

Map<Object, Map<Object, Double>> sumF1 = list.stream().collect(
                Collectors.groupingBy(
                        TABLEX::getF3,
                        Collectors.groupingBy(TABLEX::getF4,
                                Collectors.summingDouble(TABLEX::getF1))));
System.out.println(sumF1);
Run Code Online (Sandbox Code Playgroud)

输出:

{a={b=2.0}, c={d=7.0}}
Run Code Online (Sandbox Code Playgroud)

相当于SELECT sum(f2) FROM TABLEX GROUP BY f3, f4

Map<Object, Map<Object, Double>> sumF2 = list.stream().collect(
                Collectors.groupingBy(
                        TABLEX::getF3,
                        Collectors.groupingBy(TABLEX::getF4,
                                Collectors.summingDouble(TABLEX::getF2))));
System.out.println(sumF2);
Run Code Online (Sandbox Code Playgroud)

输出:

{a={b=4.0}, c={d=8.0}}
Run Code Online (Sandbox Code Playgroud)

编辑:

为了得到预期的结果

sumF1.forEach((f3, m) -> m.forEach((f4, sum) -> System.out.println(sum
                + " " + sumF2.get(f3).get(f4) + " " + f3 + " " + f4)));
Run Code Online (Sandbox Code Playgroud)

输出:

2.0 4.0 a b
7.0 8.0 c d
Run Code Online (Sandbox Code Playgroud)