解决<Map<String,Object>>List里缺失数据的问题:跳出来你会看得更全面
记一次问题解决思路
需求是根据时间范围查一些数据然后计算,假设有180个设备,理想状态下应该查回来180条数据,
数据格式是<Map<String,Object>>List 里面每个map就是一条数据,理想状态下它们是连续的,也就是
1 2 3 4 | {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} .... |
这样的
那么问题就来了,假设库里这个时间段有一个设备或多个设备没有上传数据,那么就会出现断裂
1 2 3 4 5 6 7 | {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的记录
1 2 3 4 5 6 7 8 | {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一定不一样
我就可以在这里添加一条数据那就完事
但是不是那么容易
因为我循环是这样对比的
1 | 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就是哪里缺少了数据
像这样
1 2 3 4 5 | 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末尾位置
我突然对大佬产生了仰慕之情,大佬就是大佬,看问题的角度都不一样(还是自己太菜了)
这件事说明解决问题的时候不要钻牛角尖,要尝试从更高的角度去解决问题,可能没有那么复杂呢
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话