ConcurrentHashMap终于安排上了--按半年统计用户访问量
前言
需求查询系统登录日志表, 按半年为周期统计用户访问量
这里按半年统计用户访问量是指从最早的一条记录到当前时间的所有记录按半年这个周期进行统计, mysql中有统计季度的函数Quarter, 以下是按季度统计的sql和查询结果, 按正序排:
SQL
SELECT CONCAT( YEAR (create_time), QUARTER (create_time) ) m, COUNT( DATE_FORMAT(create_time, '%Y-%m') ) count FROM login_log AS a GROUP BY m ORDER BY m ASC
查询结果
service层封装后的结果为:
List<StatisticsViewVo> resultVos = getQuarterViewVos(sourceList, calendar);
目标结果
{ "success": true, "payload": { "data": [ { "m": "2019上半年", "count": 0 }, { "m": "2019下半年", "count": 3 }, { "m": "2020上半年", "count": 6 }, { "m": "2020下半年", "count": 11 } ] } }
思路
-
将list中的vo对象中的m和count按键值对存入map中
-
在遍历list时根据map的containsKey方法判断获取对应key的value
-
将该value存入对应的上半年或下半年统计数中
-
删除统计过的元素
不啰嗦了, 看代码吧, 略low, 好在能用..
代码
resultVos = getQuarterViewVos(sourceList, calendar); // 遍历resultVos,存入map ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); for (StatisticsViewVo vo : resultVos) { map.put(vo.getM(), vo.getCount()); } List<StatisticsViewVo> resultList = Lists.newArrayList(); // 再次遍历resultVos if (CollectionUtils.isNotEmpty(resultVos)) { Iterator<StatisticsViewVo> iterator = resultVos.iterator(); while (iterator.hasNext()) { StatisticsViewVo vo = iterator.next(); String yearAndQuarter = vo.getM(); String year = yearAndQuarter.substring(0, 4); String year1 = year + "1"; String year2 = year + "2"; String year3 = year + "3"; String year4 = year + "4"; String ayear = year + "上半年"; String pyear = year + "下半年"; int acount = 0; int pcount = 0; // 统计该year的所有季度的访问量,并将12季度统计到上半年,34季度统计到下半年 if (map.containsKey(year1)) { acount += map.get(year1); } if (map.containsKey(year2)) { acount += map.get(year2); } if (map.containsKey(year3)) { pcount += map.get(year3); } if (map.containsKey(year4)) { pcount += map.get(year4); } if (map.containsKey(year1) || map.containsKey(year2)) { StatisticsViewVo avo = new StatisticsViewVo(); avo.setM(ayear); avo.setCount(acount); resultList.add(avo); } if (map.containsKey(year3) || map.containsKey(year4)) { StatisticsViewVo pvo = new StatisticsViewVo(); pvo.setM(pyear); pvo.setCount(pcount); resultList.add(pvo); } // 移除map中以该year开头的key,因为需要多次遍历不能用迭代器,更不能用普通HashMap因为会抛并发异常 for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); if (key.startsWith(year)) { map.remove(key); } } }
作者:习惯沉淀
如果文中有误或对本文有不同的见解,欢迎在评论区留言。
如果觉得文章对你有帮助,请点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
扫码关注一线码农的学习见闻与思考。
回复"大数据","微服务","架构师","面试总结",获取更多学习资源!