Java流过滤器值的总和 [英] Java stream filter sum of values

查看:309
本文介绍了Java流过滤器值的总和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 MonitoredData 的类,用于描述活动,开始时间和结束时间。属性为 activityLabel startTime endTime 。我必须使用流来划分和过滤这些活动,这些活动的总持续时间超过10小时。我设法计算了持续时间的总和,并根据活动将它们分组:

I have a class called MonitoredData with which describes an activity, its starting time and ending time. The attributes are activityLabel, startTime, endTime. I have to group and filter these activities, using streams, the activities which have the total duration of more than 10 hours. I managed to make the sum of durations and group them according to the activity using this:

Map<String, Long> map4 = new HashMap<String, Long>();

map4 = data.stream()
    .collect(
        Collectors.groupingBy(
            MonitoredData::getActivity, 
            Collectors.summingLong(MonitoredData::getDuration)
        )
    ); //getDuration returns end Time - startTime in milliseconds

但我还没有设法添加过滤器。我尝试使用:

But I haven't managed to add a filter. I tried using:

.filter(Collectors.summingLong(MonitoredData::getDuration) > whatever)

但很明显它不起作用。如何解决这个问题,以使其返回 Map< String,Long>

but obviously it doesn't work. How can I solve this in order to make it return a Map<String, Long>?

推荐答案

我会先做你已经完成的事情:我会将 MonitoredData 实例的流收集到地图中,按活动分组并汇总每个值中每个活动的持续时间:

I would first do as you've already done: I'd collect the stream of MonitoredData instances to a map, grouping by activity and summing the duration of each activity in each value:

Map<String, Long> map4 = data.stream()
    .collect(Collectors.groupingBy(
        MonitoredData::getActivity, 
        HashMap::new,
        Collectors.summingLong(MonitoredData::getDuration)));

细微差别在于我正在使用 的重载版本> Collectors.groupingBy 接受地图的工厂,因为在下一步中我想删除持续时间较短的条目超过10小时,并且规范不保证带有一个或两个参数的 Collectors.groupingBy 方法返回的映射是可变的。

The nuance is that I'm using the overloaded version of Collectors.groupingBy that accepts a factory for the map, because in the next step I want to remove the entries whose duration is less than 10 hours, and the spec doesn't guarantee that the map returned by the Collectors.groupingBy methods that take either one or two arguments is mutable.

这是我删除不匹配的条目的方式:

This is how I'd remove the entries that don't match:

public static final long TEN_HOURS_MS = 10 * 60 * 60 * 1000;

map4.values().removeIf(v -> v < TEN_HOURS_MS);

如果你想在一行中做所有事情,你可能想要使用 Collectors.collectingAndThen

If you want to do everything in a single line, you might want to use Collectors.collectingAndThen:

Map<String, Long> map4 = data.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.groupingBy(
            MonitoredData::getActivity, 
            HashMap::new,
            Collectors.summingLong(MonitoredData::getDuration)),
        m -> { m.values().removeIf(v -> v < TEN_HOURS_MS); return m; } ));

这里我使用了 收藏家。 collectAndThen 修改 Collectors.groupingBy 返回的地图。并且,在终结器功能中,我使用了 Collection.removeIf ,它接受谓词并删除与该谓词匹配的所有条目。

Here I've used Collectors.collectingAndThen to modify the map returned by Collectors.groupingBy. And, within the finisher function, I've used Collection.removeIf, which takes a predicate and removes all the entries that match that predicate.

这篇关于Java流过滤器值的总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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