首页 > 解决方案 > 如何使用 java 流对字段进行分组并创建摘要

问题描述

public class Call {
    private String status;
    private String callName;
}

我有一个通话清单,我必须创建一个摘要,如下所示:

public class CallSummary {
    private String callName;
    private List<ItemSummary> items;
}
public class itemSummary {
    private String status;
    private Integer percentage;
}

我的目标是显示具有某种状态的呼叫百分比,例如:

INBOUND_CALL : {
FAILED = 30%
SUCCESS = 70%
}

我如何使用 java 8 流和收集器来做到这一点?

标签: javajava-streamcollectors

解决方案


以下收集到一个状态 -> 百分比图,然后您可以将其转换为您的输出模型。此代码假定一个getStatus方法。

List<Call> calls;
Map<String,Double> statusPercents = calls.stream()
    .collect(Collectors.groupingBy(Call::getStatus,
        Collectors.collectingAndThen(Collectors.counting(), 
            n -> 100.0 * n / calls.size())));

我意识到这段代码有点难以阅读。收集器链按状态对调用进行分组,然后对每个组进行计数,最后转换为百分比。您可以(可以说)通过为收集器设置临时变量来使其更具可读性:

var percentFunction = n -> 100.0 * n / calls.size();
var collectPercent = collectingAndThen(count(), percentFunction);
var collectStatusPercentMap = groupingBy(Call::getStatus, collectPercent);

您还想按呼叫名称进行分组,但这实际上是同一件事 - 使用groupingBy然后将呼叫列表减少到CallSummary.


推荐阅读