想获取一批数据时,例如:
维度:
指标值:销售数量:****
但是从源头获取时,只获取了部分数据,做趋势处理时,因为缺少数据图例不好看,想将没有获取的数据进行补全处理,销售数量显示为0即可
实现数据补全时要考虑到通用性:
考虑以上场景,代码如下:
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=奥迪)