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