Java 8 Lambda分组同时使用X和Y.

Hug*_*nte 8 java lambda java-8

我正在寻找一个lambda来优化已检索的数据.我有一个原始结果集,如果用户没有更改我希望使用java的lambda按结果分组的日期.而且我是java的新手lambdas.

我正在寻找的lambda与这个查询相似.

select z, w, min(x), max(x), avg(x), min(y), max(y), avg(y) from table group by x, w;
Run Code Online (Sandbox Code Playgroud)

spr*_*ter 8

所以我假设您有一个对象列表,并且您想要创建一个具有给定分组的地图.我对你的x,y,w,z有点困惑,所以我会用自己的字段.但这是我将如何做到这一点:

interface Entry {
    String getGroup1();
    String getGroup2();
    int getIntData();
    double getDoubleData();
}

List<Entry> dataList;
Map<String, Map<String, IntSummaryStatistics>> groupedStats = 
    dataList.stream()
        .collect(Collectors.groupingBy(Entry::getGroup1,
            Collectors.groupingBy(Entry::getGroup2,
                Collectors.summarizingInt(Entry::getIntData))));
Run Code Online (Sandbox Code Playgroud)

然后,如果你想获得具有组A,B的项目的平均数据,那么你使用:

groupedStats.get("A").get("B").getAverage();
Run Code Online (Sandbox Code Playgroud)

如果要同时汇总多个数据集,则会更复杂一些.您需要编写自己的包装器类,可以累积多个统计信息.这是一个包含Entry中两个数据项的示例(我将它们设为int和double,以使其更有趣).

class CompoundStats {
    private final IntSummaryStatistics intDataStats = new IntSummaryStatistics();
    private final DoubleSummaryStatistics doubleDataStats = new DoubleSummaryStatistics();

    public void add(Entry entry) {
        intDataStats.accept(entry.getIntData());
        doubleDataStats.accept(entry.getDoubleData());
    }

    public CompoundStats combine(CompoundStats other) {
        intDataStats.combine(other.intDataStats);
        doubleDataStats.combine(other.doubleDataStats);
        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后可以使用此类创建自己的收集器:

Map<String, Map<String, CompoundStats>> groupedStats = 
    dataList.stream()
        .collect(Collectors.groupingBy(Entry::getGroup1,
            Collectors.groupingBy(Entry::getGroup2,
                Collector.of(CompoundStats::new, CompoundStats::add, CompoundStats::combine))));
Run Code Online (Sandbox Code Playgroud)

现在你的地图返回一个CompoundStats而不是一个IntSummaryStatistics:

groupedStats.get("A").get("B").getDoubleStats().getAverage();
Run Code Online (Sandbox Code Playgroud)

另请注意,如果您创建了一个单独的类来保存您的分组而不是使用我上面提到的两步图,那么这将更整洁.如果需要,再次不是一个困难的修改

希望这对你自己的情况很有用.

  • @LukasEder指出SQL是SQLesque问题的好语言! (3认同)