zoukankan      html  css  js  c++  java
  • 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
                }
            ]
        }
    }

    思路

    1. 将list中的vo对象中的m和count按键值对存入map中

    2. 在遍历list时根据map的containsKey方法判断获取对应key的value

    3. 将该value存入对应的上半年或下半年统计数中

    4. 删除统计过的元素

    不啰嗦了, 看代码吧, 略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);
                }
            }
        }
  • 相关阅读:
    ORB_SLAM2_Android
    Android惯性导航定位
    基于图像特征的图像哈希算法及实现
    Locality preserving hashing for fast image search: theory and applications
    OpenNI depth深度数据的数据格式
    速度快的国外镜像国家
    wget和curl
    关于wireshark
    ios app抓包分析
    浏览器同部署了https的服务器交互的过程
  • 原文地址:https://www.cnblogs.com/yadongliang/p/13527008.html
Copyright © 2011-2022 走看看