天天看點

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

原始資料

自2020-11-27 過去一周的資料,日期不連續

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

補全日期資料,沒有的日期,資料預設補0

/**
* 折線圖資料
*
* @param preDate 開始日期,不傳預設近一周
* @return
*/
public List<DailyDataChartVo> getChartData(LocalDate preDate) {
if (Objects.isNull(preDate)) {
preDate = LocalDate.now().minusWeeks(1);
    }
LocalDate endDate = LocalDate.now();
List<DailyDataChartVo> list = this.dailyDataMapper.selectChartData(preDate, endDate);
return this.completeData(preDate, endDate, list);
}

/**
* 補全資料
*
* @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;
}

/**
* 擷取間隔的日期清單
*
* @param preDate 開始日期
* @param endDate 截止日期
* @return
*/
private List<LocalDate> getRangeDays(LocalDate preDate, LocalDate endDate) {
List<LocalDate> 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;
}

      

補全後的資料

點選檢視代碼

[
    {
        "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
    }
]

      

核心方法

Stream.iterate():接收一個初始元素seed,生成從seed到f的疊代流

/**
* @param seed 初始元素
* @param f UnaryOperator,函數式接口,接收T類型參數,調用apply後傳回T本身,應用于上一個元素以産生新元素
*/
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {}

//建立一個從開始日期、每次加一天的無限流,限制到截止日期為止
Stream.iterate(preDate, c -> c.plusDays(1))
        .limit(betweenDays + 1)
        .forEach(dates::add);
      

作者:cchilei

-------------------------------------------

個性簽名:竹杖芒鞋輕勝馬 一蓑煙雨任平生

繼續閱讀