我有这样的功能:
private static Map<String, ResponseTimeStats> perOperationStats(List<PassedMetricData> scopedMetrics, Function<PassedMetricData, String> classifier)
{
Map<String, List<PassedMetricData>> operationToDataMap = scopedMetrics.stream()
.collect(groupingBy(classifier));
return operationToDataMap.entrySet().stream()
.collect(toMap(Map.Entry::getKey, e -> StatUtils.mergeStats(e.getValue())));
}
有没有办法让groupBy调用我在第2行显式执行的转换,所以我不必单独流式传输地图?
更新
以下是mergeStats()
的样子:
public static ResponseTimeStats mergeStats(Collection<PassedMetricData> metricDataList)
{
ResponseTimeStats stats = new ResponseTimeStats();
metricDataList.forEach(data -> stats.merge(data.stats));
return stats;
}
答案 0 :(得分:3)
如果您可以将StatUtils.mergeStats
重写为Collector
,则可以写
return scopedMetrics.stream().collect(groupingBy(classifier, mergeStatsCollector));
即使你不能这样做,你也可以写
return scopedMetrics.stream().collect(groupingBy(classifier,
collectingAndThen(toList(), StatUtils::mergeStats)));
答案 1 :(得分:1)
为了对PassedMetricData
个实例进行分组,您必须使用整个Stream,因为例如,第一个和最后一个PassedMetricData
可能会被分组到同一个组中。
这就是为什么分组必须是原始Stream上的终端操作的原因,您必须创建一个新的Stream才能对此分组的结果进行转换。
你可以将这两个陈述联系起来,但它不会产生太大的影响:
private static Map<String, ResponseTimeStats> perOperationStats(List<PassedMetricData> scopedMetrics, Function<PassedMetricData, String> classifier)
{
return scopedMetrics.stream()
.collect(groupingBy(classifier)).entrySet().stream()
.collect(toMap(Map.Entry::getKey, e -> StatUtils.mergeStats(e.getValue())));
}