我有一个通话清单,我必须创建一个摘要,像这样:
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流对字段进行分组并创建摘要
发布评论