使用流从列表中获取总和和最大值 [英] Getting the sum and max from a list using stream

查看:104
本文介绍了使用流从列表中获取总和和最大值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨我有一个List,数据看起来像这样

Hi I have a List where the data looks like this

[{"month":"April","day":"Friday","count":5},

{"month":"April","day":"Monday","count":6},

{"month":"April","day":"Saturday","count":2},

{"month":"April","day":"Sunday","count":1},

{"month":"April","day":"Thursday","count":7},

{"month":"April","day":"Tuesday","count":8},

{"month":"April","day":"Wednesday","count":10},

{"month":"March","day":"Friday","count":3},

{"month":"March","day":"Monday","count":2},

{"month":"March","day":"Saturday","count":15},

{"month":"March","day":"Sunday","count":11},

{"month":"March","day":"Thursday","count":4},

{"month":"March","day":"Tuesday","count":20},

{"month":"March","day":"Wednesday","count":7},

{"month":"May","day":"Friday","count":2},

{"month":"May","day":"Monday","count":0},

{"month":"May","day":"Saturday","count":7},

{"month":"May","day":"Sunday","count":4},

{"month":"May","day":"Thursday","count":8},

{"month":"May","day":"Tuesday","count":3},

{"month":"May","day":"Wednesday","count":6}]

我的对象类是

String month;
String day;
Integer count;

我想通过使用流来获得的是按月分组的计数总和以及最大计数的日期那个月。

What I want to get by using stream is sum of count grouped by month and the day with max count for that month.

所以最终结果看起来像

四月,周三,39
3月,星期二,62
5月,星期四,30

April, Wednesday, 39 March, Tuesday, 62 May, Thursday , 30

我一直在尝试使用流和分组,但没有运气。任何帮助表示赞赏。谢谢

I have been trying to use stream and grouping by but no luck. Any help is appreciated. Thanks

编辑

 Map<String, Integer> totalMap = transactions.stream().collect(Collectors.groupingBy(MonthlyTransaction::getMonth, Collectors.summingInt(MonthlyTransaction::getCount)));
     Map<String, String> maxMap = transactions.stream().collect(Collectors.groupingBy(MonthlyTransaction::getMonth)).values().stream().toMap(Object::getDay, Collextions.max(Object::getCount);

显然maxMap方法错了,但我不知道怎么写。

obviously the maxMap method is wrong but I do not know how to write it.

推荐答案

如果你想在一次通过中找到每月计数和每月最大计数的日期,我认为你需要一个自定义收集器。

If you want to find both the sum of counts per month and the day with the max count per month in a single pass, I think you need a custom collector.

首先,让我们创建一个持有者类来存储结果:

First, let's create a holder class where to store the results:

public class Statistics {

    private final String dayWithMaxCount;

    private final long totalCount;

    public Statistics(String dayWithMaxCount, long totalCount) {
        this.dayWithMaxCount = dayWithMaxCount;
        this.totalCount = totalCount;
    }

    // TODO getters and toString
}

然后,创建此方法d,返回一个收集器,累加计数和最大计数的总和,以及找到该最大值的那一天:

Then, create this method, which returns a collector that accumulates both the sum of counts and the max count, along with the day in which that max was found:

public static Collector<MonthlyTransaction, ?, Statistics> withStatistics() {
    class Acc {
        long sum = 0;
        long maxCount = Long.MIN_VALUE;
        String dayWithMaxCount;

        void accumulate(MonthlyTransaction transaction) {
            sum += transaction.getCount();
            if (transaction.getCount() > maxCount) {
                maxCount = transaction.getCount();
                dayWithMaxCount = transaction.getDay();
            }
        }

        Acc merge(Acc another) {
            sum += another.sum;
            if (another.maxCount > maxCount) {
                maxCount = another.maxCount;
                dayWithMaxCount = another.dayWithMaxCount;
            }
            return this;
        }

        Statistics finish() {
            return new Statistics(dayWithMaxCount, sum);
        }
    }
    return Collector.of(Acc::new, Acc::accumulate, Acc::merge, Acc::finish);
}

这使用本地类 Acc 累积并合并部分结果。 完成方法返回 Statistics 类的实例,该类保存最终结果。最后,我正在使用 Collector.of 基于 Acc 类的方法创建收集器。

This uses the local class Acc to accumulate and merge partial results. The finish method returns an instance of the Statistics class, which holds the final results. At the end, I'm using Collector.of to create a collector based on the methods of the Acc class.

最后,您可以使用上面定义的方法和类,如下所示:

Finally, you can use the method and class defined above as follows:

Map<String, Statistics> statisticsByMonth = transactions.stream()
    .collect(Collectors.groupingBy(MonthlyTransaction::getMonth, withStatistics()));

这篇关于使用流从列表中获取总和和最大值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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