使用流从列表中获取总和和最大值 [英] Getting the sum and max from a list using stream
问题描述
嗨我有一个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屋!