gpt4 book ai didi

Java 8 在一段滑动窗口中计数

转载 作者:行者123 更新时间:2023-11-30 10:05:46 24 4
gpt4 key购买 nike

给定以下类和数据结构,我想计算每个连续 3 小时滑动窗口的计数总和,类似于以下结果:

public class Log {
private int id;
private LocalDateTime timestamp;
private int count;
}
id   timestamp               count
1 2018-10-10T08:00:00 12
2 2018-10-10T08:30:00 5
3 2018-10-10T08:45:00 7
4 2018-10-10T09:10:00 9
5 2018-10-10T09:50:00 3
6 2018-10-10T10:15:00 8
7 2018-10-10T12:00:00 6
8 2018-10-10T12:30:00 1
9 2018-10-10T12:45:00 2
10 2018-10-10T17:30:00 4
11 2018-10-10T17:35:00 7

日志的时间戳按升序排列,从第一条记录开始,每3小时窗口(可以跨越不同的一天)的计数总和。结果将是:

2018-10-10T08:00:00 ~ 2018-10-10T10:59:00   12+5+7+9+3+8
2018-10-10T08:30:00 ~ 2018-10-10T11:29:00 5+7+9+3+8
2018-10-10T08:45:00 ~ 2018-10-10T11:44:00 7+9+3+8
2018-10-10T09:10:00 ~ 2018-10-10T12:09:00 9+3+8+6
2018-10-10T09:50:00 ~ 2018-10-10T12:09:00 3+8+6+1
2018-10-10T10:15:00 ~ 2018-10-10T13:14:00 8+6+1+2
...

我在下面有一些示例代码,但感觉效率不高(如果有大量日志),因为每次我都必须从所有日志中获取和比较过滤后的时间戳。怎么只能从当前日志比较到最后?

var logs = List.of();
logs.stream.map(log -> {
var start = log.getTimeStamp();
var end = log.getTimeStamp().plusHours(3);
var logsWithinWindow = logs.stream().filter(l -> isWithinRange(start, end, l.getTimeStamp()));
return logsWithinWindow.map(Log::getCount).sum();
});

最佳答案

如果您要计算任何持续时间内的日志,您可以使用:

int countLogsInDuration(List<Log> logs, LocalDateTime start, LocalDateTime end) {
return logs.stream()
.filter(log -> isWithinRange(log.getTimeStamp(), start, end))
.mapToInt(Log::getCount)
.sum();
}

依赖于

private static boolean isWithinRange(LocalDateTime logTimestamp, LocalDateTime start, LocalDateTime end) {
// return true or false based on comparison
}

此外,至少在您的情况下,每 3 小时计算一次日志似乎是多余的,因为您的滑动窗口大小为 30 分钟。因此,您可以计算每 30 分钟的计数,例如 8:00 到 8:30,然后是 8:30 到 9:00,依此类推。当您的滑动窗口与之前的持续时间重叠时,这将避免冗余计算的计数。

关于Java 8 在一段滑动窗口中计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55072300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com