Java 8 Stream API 筛选和标记时间范围内的 CurvePoint
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
首先,我们可以使用 Stream 的 filter 方法来筛选出符合时间范围条件的 CurveData 对象。然后,使用 flatMap 方法将每个 CurveData 对象的 curvePoints 转换成一个新的 Stream
下面是示例代码:
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 和对应的时间,你可以根据实际需求进行进一步处理。
原文地址: https://www.cveoy.top/t/topic/pdSL 著作权归作者所有。请勿转载和采集!