如何使用Java流对字段进行分组并创建摘要 [英] how to use java stream to group fields and create a summary

查看:82
本文介绍了如何使用Java流对字段进行分组并创建摘要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有一个通话清单,我必须创建一个摘要,像这样:

I have a list of calls and i have to create a summary, like this:

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

我的目标是显示具有一定状态的通话百分比 就像:

My goal is show a percentage of calls with some status like :

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

如何使用Java 8 Stream和Collector做到这一点?

how can i do it using java 8 stream and Collectors ?

推荐答案

分组的想法是嵌套,以便您拥有一个呼叫名称,然后可以进行基于状态的计数查找.我还建议对状态使用枚举

The idea behind the grouping would be to nest is in such a way that you have a call name and then status based count lookup available. I would also suggest using an enumeration for the status

enum CallStatus {
    FAILED, SUCCESS
}

并在其他类中将其改编为

and adapting it in other classes as

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

然后,您可以实现嵌套分组,并从中间结果开始,例如:

Then you can implement a nested grouping and start off with an intermediate result such as:

List<Call> sampleCalls = List.of(new Call(CallStatus.SUCCESS,"naman"),new Call(CallStatus.FAILED,"naman"),
        new Call(CallStatus.SUCCESS,"diego"), new Call(CallStatus.FAILED,"diego"), new Call(CallStatus.SUCCESS,"diego"));

Map<String, Map<CallStatus, Long>> groupedMap = sampleCalls.stream()
        .collect(Collectors.groupingBy(Call::getCallName,
                Collectors.groupingBy(Call::getStatus, Collectors.counting())));

这将为您提供

{diego={FAILED=1, SUCCESS=2}, naman={FAILED=1, SUCCESS=1}}

,您还可以进一步评估百分比. (尽管用Integer表示它们可能会失去精度,具体取决于您如何进一步评估它们.)

and you can further evaluate the percentages as well. (though representing them in Integer might lose precision depending on how you evaluate them further.)

要进一步解决,可以为基于名称的计数查找保留另一个Map:

To solve it further, you can keep another Map for the name-based count lookup as:

Map<String, Long> nameBasedCount = calls.stream()
        .collect(Collectors.groupingBy(Call::getCallName, Collectors.counting()));

,此外,将List中类型为CallSummary的汇总计算为:

and further, compute summaries of type CallSummary in a List as :

List<CallSummary> summaries = groupedMap.entrySet().stream()
        .map(entry -> new CallSummary(entry.getKey(), entry.getValue().entrySet()
                .stream()
                .map(en -> new ItemSummary(en.getKey(), percentage(en.getValue(),
                        nameBasedCount.get(entry.getKey()))))
                .collect(Collectors.toList()))
        ).collect(Collectors.toList());

其中percentage计数也可以由您使用与ItemSummary中选择的数据类型对齐的签名int percentage(long val, long total)来实现.

where percentage count be implemented by you using the signature int percentage(long val, long total) aligned with the datatype chosen in ItemSummary as well.

抽样结果:

[
CallSummary(callName=diego, items=[ItemSummary(status=FAILED, percentage=33), ItemSummary(status=SUCCESS, percentage=66)]), 
CallSummary(callName=naman, items=[ItemSummary(status=FAILED, percentage=50), ItemSummary(status=SUCCESS, percentage=50)])
]

这篇关于如何使用Java流对字段进行分组并创建摘要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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