Java 8流分组通过自定义逻辑 [英] Java 8 Stream groupingBy with custom logic

查看:111
本文介绍了Java 8流分组通过自定义逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Records的列表.其中有两个字段:LocalDateTime instantDouble data.

I have a list of Records. Which has two fields: LocalDateTime instant and a Double data.

我想按小时将所有记录分组,并创建一个Map<Integer, Double>.键(整数)是小时,值(双精度)是该小时的最后一个数据-该小时的第一个数据.

I want to groupBy all the records by Hour and create a Map<Integer, Double>. Where the keys (Integer) are hours and values(Double) are last Data of that hour - first Data of that hour.

到目前为止,我所做的是:

What I have done so far is following:

Function<Record, Integer> keyFunc = rec->rec.getInstant().getHour();
Map<Integer, List<Record>> valueMap = records.stream().collect(Collectors.groupingBy(keyFunc));

我希望值映射表保留Double而不是List<Records>.

I want the value map to hold Double instead of List<Records>.

例如:列表记录可以如下:

For Example: List records can be following:

Instant            Data
01:01:24           23.7
01:02:34           24.2
01:05:23           30.2
...
01:59:27           50.2
02:03:23           54.4
02:04:23           56.3
...
02:58:23           70.3
...

结果图应为:

Key       Value
1          26.5 (50.2-23.7)
2          15.9 (70.3-54.4)
...

推荐答案

您主要是在寻找

You are mostly looking for Collectors.mapping within the groupingBy.

Map<Integer, List<Double>> valueMap = records.stream()
        .collect(Collectors.groupingBy(keyFunc, 
                Collectors.mapping(Record::getData, Collectors.toList())));

这会将Record按其instant的小时数和此类记录的相应数据分组为List作为地图的值.根据评论进一步

This would group Records by their instant's hour and corresponding data for such records into a List as values of the map. Based on comments further

我想从最后一个数据中减去第一个数据

I want to subtract the first data from the last data

是的,列表将基于即时排序

Yes the list will be sorted list based on instant

您可以使用分组地图以如下方式获得所需的输出:

you can use the grouped map to get the desired output as:

Map<Integer, Double> output = new HashMap<>();
valueMap.forEach((k, v) -> output.put(k, v.get(v.size() - 1) - v.get(0)));


或者,您可以使用


Alternatively, you could use Collectors.mapping with Collectors.collectingAndThen further as:

Map<Integer, Double> valueMap = records.stream()
        .collect(Collectors.groupingBy(keyFunc,
                Collectors.mapping(Record::getData, 
                        Collectors.collectingAndThen(
                                Collectors.toList(), recs -> recs.get(recs.size() - 1) - recs.get(0)))));

这篇关于Java 8流分组通过自定义逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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