• 解决<Map<String,Object>>List里缺失数据的问题:跳出来你会看得更全面


    记一次问题解决思路

    需求是根据时间范围查一些数据然后计算,假设有180个设备,理想状态下应该查回来180条数据,
    数据格式是<Map<String,Object>>List 里面每个map就是一条数据,理想状态下它们是连续的,也就是

    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=1}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=2}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=3}
    ....
    

    这样的


    那么问题就来了,假设库里这个时间段有一个设备或多个设备没有上传数据,那么就会出现断裂

    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=1}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=2}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=3}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=4}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=6}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=7}
    ....
    

    可以看到,sid为5的数据没有查到.为了保证数据连续

    所以要为没有数据的设备添加一条各项value为null的记录

    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=1}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=2}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=3}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=4}
    {valMin=null, valAvg=null, valMax=null, sid=5}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=6}
    {valMin=5.0, valAvg=27.933, valMax=37.9, sid=7}
    ....
    

     就像这样

     看起来是不是很容易,其实确实容易,但是在这里走了弯路,所以要记录下来
     最开始我是想着这还不简单,我把最大的设备数量拿到,然后循环设备从1到180,然后看哪个map的sid和我的记录不一样
     比方说循环到5,结果因为缺失了sid为5的数据,所以这个记录的sid和我循环到的index一定不一样
     我就可以在这里添加一条数据那就完事
     

    但是不是那么容易
     
     因为我循环是这样对比的

     if((i + 1) != Integer.valueOf(Val.get(i).get("sid").toString()))   //注:i从0起  sid从1到180
    

    假设少了一条记录,那么总记录就是179条,而不是180条,这样的话到了第180次循环的时候,就会报空指针异常
     因为访问了不存在的角标 180
     
     
    那么用可以用Map的containsValue(Object value)方法来判断是否有当前这个sid吗?其实也是不行的,
    这个方法只能判断map里是否有这个值,而不能判断指定key下是否有这个值,比方说我们现在有
    valMin, valAvg, valMax, sid 这四个key,只要其中有一个包含指定的value就算包含,那么结果也是不准确的,我不能确定它包含的这个值是不是我想要的sid的值

    一时间工作似乎陷入了停滞....

    还好我旁边有大佬

    大佬说:你为什么不跳出来呢

    我说:啥跳出来???

    大佬说:你这样,你把sid作为key,把每个map作为value塞到一个map里然后放入一个List再去遍历哪里缺少了相应的sid就是哪里缺少了数据

    像这样

     Map<Integer, Map<String, Object>> listmap = new HashMap();
     for (Map<String, Object> map : Val) {
    	listmap.put(Integer.valueOf(map.get("sid").toString()), map);
     }
     
    

     塞进去
     
     然后这样

    for (int i = 0; i < sid; i++) {
        if (!listmap.containsKey(i + 1)) {
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("sid", i + 1);
            hashMap.put("ValMax", null);
            hashMap.put("ValMin", null);
            hashMap.put("ValAvg", null);
            Val.add(i, hashMap);
            continue;
        }
    }

    注:add里要加i,否则会添加到list末尾位置

    我突然对大佬产生了仰慕之情,大佬就是大佬,看问题的角度都不一样(还是自己太菜了)

    这件事说明解决问题的时候不要钻牛角尖,要尝试从更高的角度去解决问题,可能没有那么复杂呢

     

    学习时的痛苦是暂时的 未学到的痛苦是终生的
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    整数安全
    Apache HTTP Server 处理连接的方式不能扩展,无法满足互联网不断发展的需求
    UNIX password system
    ws 应用场景
    事件驱动架构在 vivo 内容平台的实践 https://mp.weixin.qq.com/s/DpaSVMXSNomXsXb0dma0CA
    dmesg
    GraphQL及元数据驱动架构在后端BFF中的实践
    指向字符串的指针
    登录加密算法破解秘籍
    内存键值对存储
  • 原文地址:https://www.cnblogs.com/juanxincai/p/13032750.html
Copyright © 2020-2023  润新知