Java 代码示例:从 CurveData 列表中获取指定时间范围内的 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,并标记每个 CurvePoint 的时间:

可以通过以下代码来实现从一个日期排序好的 List 中查询时间范围条件的 CurvePoint,并标记每个 CurvePoint 的时间:

public class Main {
    public static void main(String[] args) {
        List<CurveData> curveDataList = new ArrayList<>(); // 假设已有排序好的 CurveData 列表

        LocalDate startDate = LocalDate.of(2021, 1, 1); // 起始日期
        LocalDate endDate = LocalDate.of(2021, 1, 10); // 结束日期

        List<CurvePoint> result = getCurvePointsInRange(curveDataList, startDate, endDate);

        for (CurvePoint curvePoint : result) {
            System.out.println("SerialNo: " + curvePoint.getSerialNo() + ", Time: " + curvePoint.getTime());
        }
    }

    public static List<CurvePoint> getCurvePointsInRange(List<CurveData> curveDataList, LocalDate startDate, LocalDate endDate) {
        List<CurvePoint> result = new ArrayList<>();

        for (CurveData curveData : curveDataList) {
            if (curveData.getCurveDate().isAfter(endDate)) {
                break; // 如果 CurveData 的日期在结束日期之后,结束循环
            }

            if (curveData.getCurveDate().isBefore(startDate)) {
                continue; // 如果 CurveData 的日期在起始日期之前,跳过当前循环
            }

            for (CurvePoint curvePoint : curveData.getCurvePoints()) {
                curvePoint.setTime(getCurvePointTime(curveData.getCurveDate(), curvePoint.getSerialNo()));
                result.add(curvePoint);
            }
        }

        return result;
    }

    public static LocalTime getCurvePointTime(LocalDate curveDate, int serialNo) {
        int hours = (serialNo - 1) / 2; // 计算小时数
        int minutes = (serialNo - 1) % 2 * 30; // 计算分钟数

        return LocalTime.of(hours, minutes);
    }
}

在上面的示例代码中,我们首先定义了一个 startDate 和 endDate 来表示时间范围,然后调用 getCurvePointsInRange 方法来获取时间范围内的 CurvePoint 列表。该方法会遍历 CurveData 列表,通过判断 CurveData 的日期是否在时间范围内来决定是否处理当前 CurveData。如果符合条件,则遍历 CurveData 的 CurvePoint 列表,并使用 getCurvePointTime 方法计算每个 CurvePoint 的时间。最后,将每个 CurvePoint 添加到结果列表中并返回。

Java 代码示例:从 CurveData 列表中获取指定时间范围内的 CurvePoint 并标记时间

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

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