如何使用Java流对字段进行分组并创建摘要 [英] how to use java stream to group fields and create a summary
问题描述
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屋!