Java 8 Lambda分组同时使用X和Y. [英] Java 8 Lambda groupingBy X and Y simultaneously

查看:121
本文介绍了Java 8 Lambda分组同时使用X和Y.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking for a lambda to refine the data already retrieved. I have a raw resultset, if the user do not change the date I want use java's lambda to group by the results for then. And I'm new to lambdas with java.

我正在寻找的lambda与此查询相似。

The lambda I'm looking for works simliar to this query.

select z, w, min(x), max(x), avg(x), min(y), max(y), avg(y) from table group by x, w;


推荐答案

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

So I'm assuming you have a List of objects and you want to create a map with the given groupings. I am a bit confused by your x, y, w, z so I'll use my own fields. But Here's how I would do it:

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))));

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

Then if you want to get, say, the average of data for items with groups A, B then you use:

groupedStats.get("A").get("B").getAverage();

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

If you want to summarise more than one set of data simultaneously then it gets a bit more complicated. You need to write your own wrapper class that can accumulate multiple statistics. Here's an example with both data items in Entry (I made them an int and a double to make it a bit more interesting).

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;
    }
}

然后可以使用此类创建自己的收藏家:

This class can then be used to create your own collector:

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))));

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

Now your maps return a CompoundStats instead of an IntSummaryStatistics:

groupedStats.get("A").get("B").getDoubleStats().getAverage();

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

Also note that this would be neater if you created a separate class to hold your groupings rather than using the two step map I've proposed above. Again not a difficult modification if required.

希望这在你自己的情况下很有用。

Hopefully this is useful in your own case.

这篇关于Java 8 Lambda分组同时使用X和Y.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆