Java流筛选器值之和
我有一个名为Java流筛选器值之和,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个名为monitoredata的类,它描述了一个活动及其开始时间和结束时间。这些属性是activityLabel,startTime,endTime。我必须使用流对这些活动进行分组和筛选,这些活动的总持续时间超过10小时。我设法算出了持续时间的总和,并使用以下方法根据活动对其进行分组: Map<String, Long> map4 = new HashMap<String, Long>(); map4 = data.stream() .collect(
monitoredata
的类,它描述了一个活动及其开始时间和结束时间。这些属性是activityLabel
,startTime
,endTime
。我必须使用流对这些活动进行分组和筛选,这些活动的总持续时间超过10小时。我设法算出了持续时间的总和,并使用以下方法根据活动对其进行分组:
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
但很明显,它不起作用。我如何解决这个问题以使它返回一个
Map
?我想这就是您想要的,使用
Map Map=Maps.filterValues(data.stream()
.collect(收集器.groupingBy
(MonitoredData::getActivity,Collectors.summingLong
(MonitoredData::getDuration)
)),值->值>3);
很明显,您可以编写自己的方法来像这样过滤地图,但因为它已经存在,所以在如此流行的库中。。。如何使用纯流:我不知道,但这可能会令人满意。在获得地图后添加以下代码:
map4.entrySet().stream()
.filter(a -> a.getValue() > whatever)
.collect(Collectors.joining());
这个怎么样?我接电话,你们需要自己测试
map = map.entrySet()
.stream()
.filter(it->TimeUnit.MILLISECONDS.toHours(it.getValue())>10)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
或使用收集器#收集然后
:
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))
));
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; } ));
首先,我会像您已经做的那样:我会将
MonitoredData
实例流收集到一个映射中,按活动分组,并将每个活动的持续时间和每个值相加:
Map<String, Long> map4 = data.stream()
.collect(Collectors.groupingBy(
MonitoredData::getActivity,
HashMap::new,
Collectors.summingLong(MonitoredData::getDuration)));
如果要在一行中完成所有操作,可能需要使用收集器。CollectingAnd然后:
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))
));
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; } ));
Map map4=data.stream()
收集,收集收集,然后收集(
收集者分组(
MonitoredData::getActivity,
HashMap::新建,
Collectors.summingLong(MonitoredData::getDuration)),
m->{m.values().removeIf(v->v<10小时毫秒);返回m;});
在这里,我用来修改收集器.groupingBy
返回的映射。在finisher函数中,我使用了,它接受一个谓词并删除与该谓词匹配的所有条目。在collect
操作之前添加.filter
?您应该首先映射obj->(obj,sumDuration)
,然后对结果对象应用过滤器。我正在打电话,也许你的问题更像是过滤。你可以通过分组/合并然后过滤来完成你的任务。只需注意:不要用你从未使用过的对象初始化变量。代码中的=new HashMap()
介于误导和荒谬之间。map4
的结果值将是返回的任何collect
,这是由于您的赋值,之前使用HashMap
初始化它,对结果没有影响。非常整洁!完全忘了你可以用番石榴做那件事。干得好。从本质上说,我昨晚想到了removeOf
,但我不确定,我在打电话,无法测试。你的方法更清楚地描述了从地图上删除的持续时间小于10的时间。
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; } ));