为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Java Streams 按属性将对象列表组合在一起

使用 Java Streams 按属性将对象列表组合在一起

哔哔one 2022-03-10 21:55:21
我有一个 SensorSample POJO 列表public class SensorSample {    private Device.SensorType sensorType; // This is an enum    private double sample;    private long timestamp;    // Constructor    // Setters    // Getters}我需要按 对它们进行分组timestamp,以便SensorSample同一天的所有 s 都在一起。然后我需要减少它们,这样我SensorSample每天只有一个,它的值是当天所有对象sample的值的平均值。sample有没有办法用 Streams 做到这一点?到目前为止,我将它们组合在一起:Map<Long, List<SensorSample>> yearSamples = samples.stream()                .collect(groupingBy(sample -> SECONDS_IN_A_DAY*Math.floorDiv(sample.getTimestamp(), SECONDS_IN_A_DAY)));但我不知道如何更进一步。
查看完整描述

2 回答

?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

像这样的东西,我想。要查找组的平均数:


Map<Long, Double> averages = samples.stream()

  .collect(groupingBy(SensorSample::getTimestamp,

   averagingDouble(SensorSample::getSample)));

我当天没有扩展您的公式,我认为如果我只是打电话getTimestamp并省略详细信息,它会更具可读性。如果您将getDay方法添加到SensorSample.


如果您提供了 MCVE,这也将更容易测试,因为只有一个部分类可以继续测试上面的代码有点困难。


查看完整回答
反对 回复 2022-03-10
?
www说

TA贡献1775条经验 获得超8个赞

结果似乎您想要 aList<SensorSample>之后的每个组groupingBy都减少为单个SensorSample.


List<SensorSample> result = samples.stream()

                .collect(groupingBy(sample -> SECONDS_IN_A_DAY*Math.floorDiv(sample.getTimestamp(), SECONDS_IN_A_DAY))

                .entrySet()

                .stream()

                .map(e -> {

                    SensorSample sensorSample = new SensorSample();

                    sensorSample.setTimestamp(e.getKey());

                    double average = e.getValue().stream()

                            .mapToDouble(SensorSample::getSample)

                            .average().orElse(0);

                    sensorSample.setSample(average);

                    sensorSample.setSensorType(e.getValue().get(0).getSensorType());

                    return sensorSample;

                }).collect(Collectors.toList());

map逻辑似乎有点大,因此我会考虑将其重构为这样的方法:


private static SensorSample apply(Map.Entry<Long, List<SensorSample>> e) {

        SensorSample sensorSample = new SensorSample();

        sensorSample.setTimestamp(e.getKey());

        double average = e.getValue().stream()

                .mapToDouble(SensorSample::getSample)

                .average().orElse(0);

        sensorSample.setSample(average);

        sensorSample.setSensorType(e.getValue().get(0).getSensorType());

        return sensorSample;

}

然后流管道将变为:


List<SensorSample> result = samples.stream()

                .collect(groupingBy(sample -> SECONDS_IN_A_DAY*Math.floorDiv(sample.getTimestamp(), SECONDS_IN_A_DAY))

                .entrySet()

                .stream()

                .map(Main::apply)

                .collect(Collectors.toList());

Main包含该apply方法的类在哪里。


查看完整回答
反对 回复 2022-03-10
  • 2 回答
  • 0 关注
  • 184 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号