1. 程式人生 > 實用技巧 >Java8-無限流補全日期,折線圖補零

Java8-無限流補全日期,折線圖補零

需求:
專案中經常會遇到折線圖等隨日期、月份變化的趨勢圖,但有時會出現日期不連續的情況,圖表就會有中斷,需要在後臺將日期資料補全,sql或者程式裡都可以處理。
而Java8提供的無限流,可以更方便的實現補全日期的操作,因為日期是連續遞增的,看似無限序列。
原始資料:2020-11-27過去一週的資料

demo:沒有的日期資料,預設補0
Controller:
/** * 折線圖資料 * * @param preDate 開始日期,不傳預設近一週 * @return */ @GetMapping("chart") public List<DailyDataChartVo> getChartData(@RequestParam(value = "date", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate preDate) { return this.dailyDataService.getChartData(preDate); }


Service:
`/**
* 折線圖資料
*
* @param preDate 開始日期,不傳預設近一週
* @return
/
public List getChartData(LocalDate preDate) {
if (Objects.isNull(preDate)) {
preDate = LocalDate.now().minusWeeks(1);
}
LocalDate endDate = LocalDate.now();
List list = this.dailyDataMapper.selectChartData(preDate, endDate);
return this.completeData(preDate, endDate, list);
}
/
*
* 獲取間隔的日期列表
*
* @param preDate 開始日期
* @param endDate 截止日期
* @return
*/
private List getRangeDays(LocalDate preDate, LocalDate endDate) {
List dates = new ArrayList<>();
//間隔的天數
long betweenDays = ChronoUnit.DAYS.between(preDate, endDate);
if (betweenDays < 1) {
//開始日期<=截止日期
return dates;
}
//建立一個從開始日期、每次加一天的無限流,限制到截止日期為止
Stream.iterate(preDate, c -> c.plusDays(1))
.limit(betweenDays + 1)
.forEach(dates::add);
return dates;
}

   /**
    * 補全資料
    *
    * @param preDate 開始日期
    * @param endDate 截止日期
    * @param oldList 未補全的列表
    * @return 補全後的列表
    */
   private List<DailyDataChartVo> completeData(LocalDate preDate, LocalDate endDate, List<DailyDataChartVo> oldList) {
       List<DailyDataChartVo> newList = new ArrayList<>();
       if (CollectionUtils.isEmpty(oldList)) {
           return newList;
       }
       //間隔的日期列表
       List<LocalDate> dates = this.getRangeDays(preDate, endDate);
       Map<LocalDate, DailyDataChartVo> map = oldList.stream()
               .collect(Collectors.toMap(DailyDataChartVo::getDate, Function.identity()));
       dates.forEach(c -> {
           if (map.containsKey(c)) {
               newList.add(map.get(c));
           } else {
               //沒有這一天的資料,預設補0
               newList.add(new DailyDataChartVo(c, BigDecimal.ZERO));
           }
       });
       return newList;
   }`

補全後的資料
[ { "date": "2020-11-20", "revenue": 22.88 }, { "date": "2020-11-21", "revenue": 93.06 }, { "date": "2020-11-22", "revenue": 0 }, { "date": "2020-11-23", "revenue": 7.99 }, { "date": "2020-11-24", "revenue": 0 }, { "date": "2020-11-25", "revenue": 50.98 }, { "date": "2020-11-26", "revenue": 0 }, { "date": "2020-11-27", "revenue": 0 } ]