在 Java 中将地图从每日数据转换为每周数据
Transform a map from daily data to weekly data in Java
我有一张 LocalDate
的地图和带有每日数据的整数。现在我想用每周数据创建一个新地图,这意味着新地图将包含当我们总结前一个条目和当前条目下的整数时的累积计数。我被困在这个。谁能帮我设计一个算法。我是 Java Stream api 的新手,如果可以使用 Stream API 它会
示例数据:
在图像中,我尝试遍历 weeklyMap,然后在其中遍历 dailyMap。但是我不确定如何在代码中实现它(Java)。
编辑
代码片段:
Map.Entry<LocalDate, Integer> prevEntry = null;
boolean firstTime = true;
for (Map.Entry<LocalDate, Integer> currEntry : weeklyMap.entrySet()) {
if (firstTime) {
prevEntry = currEntry;
firstTime = false;
if (weeklyMap.containsKey(currEntry.getKey())) {
weeklyMap.put(currEntry.getKey(), currEntry.getValue());
}
} else {
for (Map.Entry<LocalDate, Integer> todayEntry : dailyMap.entrySet()) {
if (prevEntry.getKey().equals(todayEntry.getKey())) {
prevEntry.setValue(todayEntry.getValue());
} else if(todayEntry.getKey().isAfter(prevEntry.getKey()) && todayEntry.getKey().isBefore(currEntry.getKey())) {
currEntry.setValue(currEntry.getValue() + todayEntry.getValue());
}
}
}
}
似乎最简单的方法是首先构建一个日累积总和图,然后只过滤掉星期一:
public static Map<LocalDate, Integer> cumulativeWeeklySum(SortedMap<LocalDate, Integer> data) {
AtomicInteger cumulativeSum = new AtomicInteger(0);
return data.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> cumulativeSum.addAndGet(e.getValue())))
.entrySet().stream()
.filter(e -> e.getKey().getDayOfWeek() == DayOfWeek.MONDAY || e.getKey().equals(data.lastKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
编辑:
如果要保留结果图的顺序,可以修改最后的collect()
调用:
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue,
(v1, v2) -> { throw new RuntimeException("Duplicate key - can't happen"); },
TreeMap::new));
我认为你应该包括验证 currentEntry.key == todayEntry.key
的边缘情况,然后总结以前的值。
代码可能看起来像这样:
if(todayEntry.getKey().equals(currEntry.getKey())) {
currEntry.setValue(currEntry.getValue() + todayEntry.getValue() + prevEntry.getValue());
}
我有一张 LocalDate
的地图和带有每日数据的整数。现在我想用每周数据创建一个新地图,这意味着新地图将包含当我们总结前一个条目和当前条目下的整数时的累积计数。我被困在这个。谁能帮我设计一个算法。我是 Java Stream api 的新手,如果可以使用 Stream API 它会
示例数据:
在图像中,我尝试遍历 weeklyMap,然后在其中遍历 dailyMap。但是我不确定如何在代码中实现它(Java)。
编辑
代码片段:
Map.Entry<LocalDate, Integer> prevEntry = null;
boolean firstTime = true;
for (Map.Entry<LocalDate, Integer> currEntry : weeklyMap.entrySet()) {
if (firstTime) {
prevEntry = currEntry;
firstTime = false;
if (weeklyMap.containsKey(currEntry.getKey())) {
weeklyMap.put(currEntry.getKey(), currEntry.getValue());
}
} else {
for (Map.Entry<LocalDate, Integer> todayEntry : dailyMap.entrySet()) {
if (prevEntry.getKey().equals(todayEntry.getKey())) {
prevEntry.setValue(todayEntry.getValue());
} else if(todayEntry.getKey().isAfter(prevEntry.getKey()) && todayEntry.getKey().isBefore(currEntry.getKey())) {
currEntry.setValue(currEntry.getValue() + todayEntry.getValue());
}
}
}
}
似乎最简单的方法是首先构建一个日累积总和图,然后只过滤掉星期一:
public static Map<LocalDate, Integer> cumulativeWeeklySum(SortedMap<LocalDate, Integer> data) {
AtomicInteger cumulativeSum = new AtomicInteger(0);
return data.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> cumulativeSum.addAndGet(e.getValue())))
.entrySet().stream()
.filter(e -> e.getKey().getDayOfWeek() == DayOfWeek.MONDAY || e.getKey().equals(data.lastKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
编辑:
如果要保留结果图的顺序,可以修改最后的collect()
调用:
.collect(Collectors.toMap(
Map.Entry::getKey, Map.Entry::getValue,
(v1, v2) -> { throw new RuntimeException("Duplicate key - can't happen"); },
TreeMap::new));
我认为你应该包括验证 currentEntry.key == todayEntry.key
的边缘情况,然后总结以前的值。
代码可能看起来像这样:
if(todayEntry.getKey().equals(currEntry.getKey())) {
currEntry.setValue(currEntry.getValue() + todayEntry.getValue() + prevEntry.getValue());
}