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

我有一个 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)));

但我不知道如何更进一步。


哔哔one
浏览 186回答 2
2回答

慕桂英4014372

像这样的东西,我想。要查找组的平均数:Map<Long, Double> averages = samples.stream()&nbsp; .collect(groupingBy(SensorSample::getTimestamp,&nbsp; &nbsp;averagingDouble(SensorSample::getSample)));我当天没有扩展您的公式,我认为如果我只是打电话getTimestamp并省略详细信息,它会更具可读性。如果您将getDay方法添加到SensorSample.如果您提供了 MCVE,这也将更容易测试,因为只有一个部分类可以继续测试上面的代码有点困难。

www说

结果似乎您想要 aList<SensorSample>之后的每个组groupingBy都减少为单个SensorSample.List<SensorSample> result = samples.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(groupingBy(sample -> SECONDS_IN_A_DAY*Math.floorDiv(sample.getTimestamp(), SECONDS_IN_A_DAY))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .entrySet()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(e -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SensorSample sensorSample = new SensorSample();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sensorSample.setTimestamp(e.getKey());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; double average = e.getValue().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .mapToDouble(SensorSample::getSample)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .average().orElse(0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sensorSample.setSample(average);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sensorSample.setSensorType(e.getValue().get(0).getSensorType());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return sensorSample;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }).collect(Collectors.toList());map逻辑似乎有点大,因此我会考虑将其重构为这样的方法:private static SensorSample apply(Map.Entry<Long, List<SensorSample>> e) {&nbsp; &nbsp; &nbsp; &nbsp; SensorSample sensorSample = new SensorSample();&nbsp; &nbsp; &nbsp; &nbsp; sensorSample.setTimestamp(e.getKey());&nbsp; &nbsp; &nbsp; &nbsp; double average = e.getValue().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .mapToDouble(SensorSample::getSample)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .average().orElse(0);&nbsp; &nbsp; &nbsp; &nbsp; sensorSample.setSample(average);&nbsp; &nbsp; &nbsp; &nbsp; sensorSample.setSensorType(e.getValue().get(0).getSensorType());&nbsp; &nbsp; &nbsp; &nbsp; return sensorSample;}然后流管道将变为:List<SensorSample> result = samples.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(groupingBy(sample -> SECONDS_IN_A_DAY*Math.floorDiv(sample.getTimestamp(), SECONDS_IN_A_DAY))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .entrySet()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(Main::apply)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());Main包含该apply方法的类在哪里。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java