对数据进行补全

想获取一批数据时,例如:

维度:

  1. 日期:2023-01-03 ~ 2023-02-03
  2. 品牌:【吉利、比亚迪、宝马】

指标值:销售数量:****

但是从源头获取时,只获取了部分数据,做趋势处理时,因为缺少数据图例不好看,想将没有获取的数据进行补全处理,销售数量显示为0即可

实现数据补全时要考虑到通用性:

  1. 数据属于不同的类
  2. 要补入不同的类字段中,可能是date、code、name、type........
  3. 可能会补多个维度

考虑以上场景,代码如下:

主方法


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; 
import lombok.Data;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 
 */

@Data
class Obj{
    private LocalDate bizDate;
    private String name;
    private String carTypeCode;
    public Obj(){}
    public Obj(LocalDate bizDate,String name,String carTypeCode){
        this.bizDate = bizDate;
        this.name = name;
        this.carTypeCode = carTypeCode;
    }
}
public class FillData{
    public static void main(String[] args) {
        // 创建各种维度,key值要跟补全对象的字段名称一致
        Map> map = new HashMap<>(16);
        map.put("bizDate", Arrays.asList(LocalDate.of(2023,1,2),LocalDate.of(2023,8,1)));
        map.put("name", Arrays.asList("张三","李四"));
        map.put("carTypeCode", Arrays.asList("奥迪","宝马","宝马"));

        // 添加单个数据,但最终结果是否会多于预期
        ArrayList list = new ArrayList<>(); 
        list.add(new Obj(LocalDate.of(2023,1,2),"张三","宝马"));

        // 进行维度补全
        List l1 = fillDataComplete(Obj.class,list ,map);
        l1.forEach(System.out::println);
    }
    /**
     * @param clazz     要补全的类class
     * @param dataList  要补全的集合,不可为null
     * @param map       要补全的维度数据
     */
    public static  List fillDataComplete(Class clazz,List dataList,Map> map){
        Map> stringMap = transformDefaultMap(map);
        for (T t : dataList) {
            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(t));
            // 存在多维度时需要将同一日期下的维度数据存放起来,以value串起来
            List collect = map.keySet().stream().map(item -> jsonObject.getObject(item, String.class))
                    .collect(Collectors.toList());
            String existKey = String.join(Constant.SEPARATIVE_SIGN, collect);
            // 打印已经存在的key值
            System.err.println(existKey);
            stringMap.remove(existKey);
        }
        List collect = stringMap.values().stream()
                .map(item -> JSON.parseObject(JSON.toJSONString(item), clazz))
                .collect(Collectors.toList());

        dataList.addAll(collect); 
        return dataList;
    }

    /** 将map进行笛卡尔积计算,以value拼接为key对结果map进行分类 */
    public static Map> transformDefaultMap(Map> defaultProperties){
        if(org.springframework.util.CollectionUtils.isEmpty(defaultProperties)) {
            return null;
        } 
        // 将map转为以全value为key的map
        Map> fillMap = new HashMap<>(16);
        for (Map.Entry> propertiesListEntry : defaultProperties.entrySet()) {
            // 将map中的数据放到临时map里面
            Map>  fillMapTmp = BeanUtil.copyProperties(fillMap,HashMap.class);
            fillMap.clear();
            //
            for (Object prop : propertiesListEntry.getValue()) {
                if(org.springframework.util.CollectionUtils.isEmpty(fillMapTmp)){
                    Map itemMap = new HashMap<>(16);
                    // 字段属性为key,值为value放入map里,再放入以value为key的map中
                    itemMap.put(propertiesListEntry.getKey(),prop);
                    fillMap.put(prop.toString(),itemMap);
                    continue;
                } 
                for (Map.Entry> stringMapEntry : fillMapTmp.entrySet()) {
                    Map valueMap = BeanUtil.copyProperties(stringMapEntry.getValue(),HashMap.class);
                    // 字段属性为key,值为value放入map里,再放入以value为key的map中
                    valueMap.put(propertiesListEntry.getKey(),prop);
                    fillMap.put( stringMapEntry.getKey() + Constant.SEPARATIVE_SIGN + prop , valueMap);
                }
            }
        }
        return fillMap;
    } 
}

输出结果:

存在的数据: 2023-01-02/张三/宝马
全部数据:
Obj(bizDate=2023-01-02, name=张三, carTypeCode=宝马)
Obj(bizDate=2023-08-01, name=张三, carTypeCode=宝马)
Obj(bizDate=2023-01-02, name=李四, carTypeCode=奥迪)
Obj(bizDate=2023-08-01, name=李四, carTypeCode=奥迪)
Obj(bizDate=2023-01-02, name=李四, carTypeCode=宝马)
Obj(bizDate=2023-08-01, name=张三, carTypeCode=奥迪)
Obj(bizDate=2023-08-01, name=李四, carTypeCode=宝马)
Obj(bizDate=2023-01-02, name=张三, carTypeCode=奥迪)

你可能感兴趣的:(java)