zoukankan      html  css  js  c++  java
  • Java8-无限流补全日期,折线图补零

    原始数据

    自2020-11-27 过去一周的数据,日期不连续

    补全日期数据,没有的日期,数据默认补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

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

    个性签名:竹杖芒鞋轻胜马 一蓑烟雨任平生

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    LRU Cache & Bloom Filter
    并查集
    WebRTC开发者必备 | 《WebRTC1.0: 浏览器间实时通讯》中文版免费下载
    数据科学真的是一份有前途的工作吗?
    教育场景下的实时音频解决方案
    《周四橄榄球之夜》流媒体视频拆解:Twitch VS Amazon Prime
    C语言之父Dennis Ritchie告诉你:如何成为世界上最好的程序员?
    视频技术详解:RTMP H5 直播流技术解析
    从理论到实践,全方位认识HTTP/2
    使用Core Audio实现VoIP通用音频模块
  • 原文地址:https://www.cnblogs.com/cchilei/p/15493342.html
Copyright © 2011-2022 走看看