Item将工作表中的对象分组items为对象列表Group,每个组存储与一分钟相关的数据。
组内的数据value必须分组为给定间隔的算术平均值(以秒为单位)。如果源工作表中没有当前间隔 N 的数据,则重复上一个间隔的值。如果组中的第一个区间没有足够的数据,则复制前一组的最后一个区间。
间隔始终小于或等于 60 秒。并将一分钟分成相等的秒数,没有余数。
public class Item {
private int id;
private String time;
private double value;
// Getters, setters, constructors...
}
public class Group {
private int id;
private List<Item> items;
// Getters, setters, constructors...
}
对于原始列表,持续时间间隔 = 30:
List<Item> items = List.of(
new Item(1, "19/09/2020 1:03:00 AM", 1.0),
new Item(2, "19/09/2020 1:03:03 AM", 1.3),
new Item(3, "19/09/2020 1:03:15 AM", 1.1),
new Item(4, "19/09/2020 1:03:47 AM", 1.2),
new Item(5, "19/09/2020 1:03:57 AM", 1.6),
new Item(6, "19/09/2020 1:04:04 AM", 1.8),
new Item(7, "19/09/2020 1:04:43 AM", 1.9),
new Item(8, "19/09/2020 1:04:44 AM", 2.1),
new Item(9, "19/09/2020 1:05:30 AM", 1.8),
new Item(10, "19/09/2020 1:05:46 AM", 2.3)
);
结果应该是:
List.of(
new Group(1, List.of(
new Item(1, "19/09/2020 1:03:00 AM", 1.13), // первые 30 сек value = (1.0 + 1.3 + 1.1) / 3
new Item(2, "19/09/2020 1:03:30 AM", 1.4) // вторые 30 сек value = (1.2 + 1.6) / 2
)),
new Group(2, List.of(
new Item(1, "19/09/2020 1:04:00 AM", 1.8), // первые 30 сек
new Item(2, "19/09/2020 1:04:30 AM", 1.5) // вторые 30 сек
)),
new Group(2, List.of(
new Item(1, "19/09/2020 1:05:00 AM", 1.5), // для первых 30 сек данных нет, в результат пойдет предыдущее значение
new Item(2, "19/09/2020 1:05:30 AM", 2.05) // вторые 30 сек
)));
签名List<Group> transform(List<Item> src, int intervalSize)
到目前为止,我所做的只是创建一个空的组列表
public class Transformer {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a", Locale.ENGLISH);
@SneakyThrows
public List<Group> transform(List<Item> source, int intervalSize) {
List<Group> target = getEmptyGroups(source);
return target;
}
@SneakyThrows
private List<Group> getEmptyGroups(List<Item> source) {
Item start = source.get(0);
Calendar startTime = Calendar.getInstance();
startTime.setTime(formatter.parse(start.getTime()));
Item end = source.get(source.size() - 1);
Calendar endTime = Calendar.getInstance();
endTime.setTime(formatter.parse(end.getTime()));
long groupTotal = ChronoUnit.MINUTES.between(startTime.toInstant(), endTime.toInstant()) + 1;
List<Group> groups = new ArrayList<>();
IntStream.iterate(0, i -> i < groupTotal, i -> i + 1)
.forEachOrdered(i -> {
Group group = new Group();
group.setId(i + 1);
groups.add(group);
});
return groups;
}
}