java - 使用流从列表中获取总和和最大值

标签 java sum max grouping java-stream

嗨,我有一个列表,其中的数据如下所示

[{"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;

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

所以最终结果看起来像这样

四月,星期三,39 三月,星期二,62 五月,星期四,30

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

编辑

 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方法是错误的,但我不知道如何写。

最佳答案

如果您想在一次遍历中找到每月计数总和以及每月最大计数的日期,我认为您需要一个自定义收集器。

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

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
}

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

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来累积和合并部分结果。 finish 方法返回 Statistics 类的实例,该类保存最终结果。最后,我使用 Collector.of基于 Acc 类的方法创建收集器。

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

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

关于java - 使用流从列表中获取总和和最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44199673/

相关文章:

Java序列化-进程崩溃后恢复序列化文件

python - 尝试编写一个程序,列出在 Python 中数字相加为素数的数字。我怎样才能修复溢出错误?

algorithm - 将数字的各个数字部分相加/求和的最快方法

c++ - 如何使用动画将 3ds max 模型导入 C++/Open GL

mysql - 通过基于最大值的连接获取完整行

c# - 如何使用linq查找具有最大值的项目?

java - 从 servlet 调用 Java 函数,函数不会执行

java - Google App Engine 中使用 Java Servlet 进行音频流传输

java - 单例和静态实用程序类

python - 当不存在行时,sqlalchemy func.sum() 返回 None