Java流filter值的总和

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

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

但我还没有设法添加filter。 我试过用:

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

但显然它不起作用。 我如何解决这个问题才能使它返回Map

我首先要做的就是你已经完成的工作:我将MonitoredData实例流收集到地图中,按活动分组并总结每个值中每个活动的持续时间:

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

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

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

 public static final long TEN_HOURS_MS = 10 * 60 * 60 * 1000; map4.values().removeIf(v -> v < TEN_HOURS_MS); 

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

 Map 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; } )); 

在这里,我使用了Collectors.collectingAndThen来修改Collectors.groupingBy返回的地图。 并且,在finisher函数中,我使用了Collection.removeIf ,它接受一个谓词并删除与该谓词匹配的所有条目。

这个怎么样? 我在电话里回答,你需要自己测试一下。

 map = map.entrySet() .stream() .filter(it->TimeUnit.MILLISECONDS.toHours(it.getValue())>10) .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue)); 

使用Collectors#collectingAndThen

 map4 = data.stream() .collect(Collectors.collectingAndThen( Collectors.groupingBy( MonitoredData::getActivity, Collectors.summingLong(MonitoredData::getDuration) ), r1 -> r1.entrySet().stream() .filter(it->TimeUnit.MILLISECONDS.toHours(it.getValue())>10) .collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue)) )); 

我认为这是您想要的,使用Google Guava Maps类:

 Map map = Maps.filterValues(data.stream() .collect(Collectors.groupingBy (MonitoredData::getActivity, Collectors.summingLong (MonitoredData::getDuration) )), value -> value > 3); 

显然你可以编写自己的方法来过滤这样的地图,但因为它已经存在,所以在如此受欢迎的库…如何用纯流做:我不知道,但也许这会令人满意。

获得地图后添加以下代码:

 map4.entrySet().stream() .filter(a -> a.getValue() > whatever) .collect(Collectors.joining());