Java 8 Stream API 筛选和标记时间范围内的 CurvePoint

已知有两个类,CurveData 和 CurvePoint,关系是 1 对多:

public class CurveData extends BasePersistable {

    /**
     * 所属水表
     */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private WaterMeter waterMeter;

    /**
     * 曲线数据日期
     */
    @Column(nullable = false)
    private LocalDate curveDate;

    /**
     * 换算因子(曲线数据小数点位数)0:x1.0,1:x0.1,2:x0.01,3:x0.001,4:x0.0001
     */
    @Column(nullable = false, columnDefinition = "tinyint")
    private int factor;

    /**
     * 曲线密度
     */
    @Column(nullable = false, columnDefinition = "tinyint")
    private int density;

    /**
     * 数据是否完整
     */
    @Column(nullable = false)
    private boolean dataFull;

    /**
     * 是否已上报
     */
    @Column(nullable = false)
    private boolean reported;

    /**
     * 对应曲线数据
     */
    @ElementCollection
    @CollectionTable(name = "curve_point")
    @OrderBy("serialNo asc")
    private List<CurvePoint> curvePoints = new ArrayList<>();

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(nullable = false)
    private LocalDateTime createdDate;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(nullable = false)
    private LocalDateTime lastModifiedDate;
}

public class CurvePoint implements Serializable {

    /**
     * 序号
     */
    @Column(nullable = false, columnDefinition = "tinyint unsigned")
    private int serialNo;

    /**
     * 正向累计流量
     */
    @Column
    private Integer forwardVal;

    /**
     * 反向累计流量
     */
    @Column
    private Integer backwardVal;

    public boolean isAvailable() {
        return forwardVal != null && backwardVal != null;
    }

    public Integer getValue() {
        if (!isAvailable()) {
            return null;
        }
        return forwardVal - backwardVal;
    }
}

其中每天 CurveData 中有 48 个 curve_point,是按 serialNo 排序好的,例如第一个点是 serialNo=1,时间是 00:00;第二个点是 serialNo=2,时间是 00:30。

现在从一个日期排序好的 List 中查询时间范围条件的 CurvePoint,例如查询 2023-01-02 12:00:00 到 2023-01-05 20:00:00 的数据,并标记每个 CurvePoint 的时间内容:可以使用 Java 8 的 Stream API 和 Lambda 表达式来实现对 CurveData 中 CurvePoint 的筛选和标记时间的操作。

首先,我们可以使用 Stream 的 filter 方法来筛选出符合时间范围条件的 CurveData 对象。然后,使用 flatMap 方法将每个 CurveData 对象的 curvePoints 转换成一个新的 Stream。接着,使用 forEach 方法遍历每个 CurvePoint 对象,并通过设置时间标记来记录时间。

下面是示例代码:

import java.time.LocalDateTime;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        // 假设已经有一个按日期排序好的 List<CurveData> 对象
        List<CurveData> curveDataList = getSortedCurveDataList();

        // 设置查询的时间范围
        LocalDateTime startTime = LocalDateTime.of(2023, 1, 2, 12, 0, 0);
        LocalDateTime endTime = LocalDateTime.of(2023, 1, 5, 20, 0, 0);

        // 筛选出符合时间范围条件的 CurvePoint,并标记时间
        List<CurvePoint> filteredCurvePoints = curveDataList.stream()
                .filter(curveData -> curveData.getCurveDate().atStartOfDay().isAfter(startTime))
                .flatMap(curveData -> curveData.getCurvePoints().stream())
                .filter(curvePoint -> curvePoint.isAvailable())
                .peek(curvePoint -> {
                    LocalDateTime dateTime = curveDataList.get(0).getCurveDate().atStartOfDay()
                            .plusMinutes((curvePoint.getSerialNo() - 1) * 30);
                    curvePoint.setDateTime(dateTime);
                })
                .collect(Collectors.toList());

        // 打印筛选出的 CurvePoint 和对应的时间
        for (CurvePoint curvePoint : filteredCurvePoints) {
            System.out.println("CurvePoint: " + curvePoint);
            System.out.println("Time: " + curvePoint.getDateTime());
        }
    }

    // 获取按日期排序好的 CurveData 列表的示例方法
    private static List<CurveData> getSortedCurveDataList() {
        // 创建一个按日期排序好的 CurveData 列表的示例方法
        List<CurveData> curveDataList = ...;
        return curveDataList;
    }
}

在上面的代码中,我们假设已经有一个按日期排序好的 CurveData 列表的示例方法getSortedCurveDataList(),你可以根据实际情况实现该方法来获取按日期排序好的 CurveData 列表。然后,我们设置查询的时间范围,并使用 Stream API 对 CurveData 进行筛选和标记时间的操作。

注意,示例代码中使用了curvePoint.setDateTime(dateTime)来设置 CurvePoint 的时间标记,这里假设 CurvePoint 类中有一个名为setDateTime的方法来设置时间标记,你可以根据实际情况修改该部分代码。另外,示例代码中打印了筛选出的 CurvePoint 和对应的时间,你可以根据实际需求进行进一步处理。

Java 8 Stream API 筛选和标记时间范围内的 CurvePoint

原文地址: https://www.cveoy.top/t/topic/pdSL 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录