如果键已生成日期,则向映射添加值



我有一个类作为实体的助手

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChildReports {
private LocalDate date;
private BigDecimal amount;
}

我在数据库中有条目,例如:

|    date         |        amount       |
+-----------------+---------------------+
| 2022-06-20      |        10000        |
| 2023-01-15      |         8000        |
| 2023-07-05      |         6500        |
| 2024-02-11      |         5000        |
| 2024-08-18      |         1000        |

现在我想填补日期之间的空白,这样之前的数字就写在没有数据的月份。最后应该是这样的:

|    date         |        amount       |
+-----------------+---------------------+
| 2022-06-20      |        10000        |
| 2022-07-20      |        10000        |
| 2022-08-20      |        10000        |
| 2022-09-20      |        10000        |
.............
| 2022-12-20      |        10000        |
| 2023-01-15      |         8000        |
| 2023-02-15      |         8000        |
| 2023-03-15      |         8000        |
and so on

在该服务中,我开始编写一个方法,在该方法中,我获取了整个日期范围,从dateStart开始,到dateEnd结束。

LocalDate dateStart = Objects.requireNonNull(childReports.stream().findFirst().orElse(null)).getDate();
LocalDate dateEnd = Objects.requireNonNull(childReports.stream().reduce((first, second) -> second).orElse(null).getDate());
long monthsBetween = ChronoUnit.MONTHS.between(dateStart, dateEnd);
List<LocalDate> totalMonths = LongStream.iterate(0,i -> i+1)
.limit(monthsBetween).mapToObj(dateStart::plusMonths)
.collect(Collectors.toList());
Map<List<LocalDate>, BigDecimal> map = new HashMap<>();

for (ChildReports childReport : childReports) {
BigDecimal amount = childReport.getAmount();
map.put(totalMonths, amount);
}
System.out.println(map);

我正确地得到了这个区间,但现在我想添加一个值-amunt,这样最后就会得到结果,正如我上面指出的那样。无法获得此结果

在找到开始日期和结束日期之间的月份之前,请确保将开始日期调整为与结束日期相同:

ChronoUnit.MONTHS.between(dateStart.withDayOfMonth(dateEnd.getDayOfMonth()), dateEnd)

使用嵌套循环,其余的事情应该非常简单。以下是一份样本报告:

class ReportRow {
private LocalDate date;
private BigDecimal amount;
// Parametrised constructor and getters
@Override
public String toString() {
return date + " | " + amount;
}
}
public class Solution {
public static void main(String[] args) {
List<ReportRow> originalReport = List.of(
new ReportRow(LocalDate.of(2022, 6, 20), BigDecimal.valueOf(10000)),
new ReportRow(LocalDate.of(2023, 1, 15), BigDecimal.valueOf(8000)),
new ReportRow(LocalDate.of(2023, 7, 5), BigDecimal.valueOf(6500)));
System.out.println("Before:");
originalReport.forEach(System.out::println);
List<ReportRow> updatedReport = new ArrayList<>();
int size = originalReport.size();
if (size > 0)
updatedReport.add(originalReport.get(0));
if (size > 1) {
for (int i = 1; i < size; i++) {
ReportRow lastRow = originalReport.get(i - 1);
ReportRow currentRow = originalReport.get(i);
BigDecimal lastAmount = lastRow.getAmount();
LocalDate dateStart = lastRow.getDate();
LocalDate dateEnd = currentRow.getDate();

if (ChronoUnit.MONTHS.between(dateStart.withDayOfMonth(dateEnd.getDayOfMonth()), dateEnd) > 1) {
for (LocalDate date = dateStart.plusMonths(1); date.isBefore(dateEnd); date = date.plusMonths(1))
updatedReport.add(new ReportRow(date, lastAmount));
} 

updatedReport.add(currentRow);
}
}
System.out.println("After:");
updatedReport.forEach(System.out::println);
}
}

输出

Before:
2022-06-20 | 10000
2023-01-15 | 8000
2023-07-05 | 6500
After:
2022-06-20 | 10000
2022-07-20 | 10000
2022-08-20 | 10000
2022-09-20 | 10000
2022-10-20 | 10000
2022-11-20 | 10000
2022-12-20 | 10000
2023-01-15 | 8000
2023-02-15 | 8000
2023-03-15 | 8000
2023-04-15 | 8000
2023-05-15 | 8000
2023-06-15 | 8000
2023-07-05 | 6500

注意:如果您计划使用Map并打算维护订单,则应使用LinkedHashMap而不是HashMap

最新更新