Loading...
墨滴

雄雄的小课堂

2021/12/15  阅读:60  主题:自定义主题1

两个map中的数据,按照相同键,将所对应的值相加方法

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂

前言

最近写代码的时候遇到了个需求,刚开始想的时候,感觉不难,挺简单的,结果写的时候,各种思考、各种费脑,耗费了点时间,终于实现了。

需求:因为一些原因,数据库中有两个表,结构一样且数据不一样,现在需要对这两个表进行按照小时分组统计数据,然后展示在前台。

效果如下:

image-20211215183448778
image-20211215183448778

需要将两个表中各个时间段的数据相加,然后重新封装返回到前台做展示。

思路分析

  • 分别按照小时分组查询两个表中的数据,查询出来的结构是一个List<Map>集合
  • 先将第一个表的结果放在一个map集合中。
  • 然后去遍历第二个结果的map集合,拿到key,去和第一个map集合的key比较,如果时间正好相等,则将两个结果的value相加,最后得到一个总的map集合
  • 将总的map集合的键和值分别取出来放在VO类中,最后在前台遍历展示。

下面贴一下实现代码。

代码实现

分别查询两个表中的数据,封装成List<Map>的形式传出去。

public List<Map<String, Object>> getFlowsHoursDiSanFangByProvince(Integer proId){
        Map<String,Object> map = new HashMap<String,Object>();
        List<Map> mapList = new ArrayList<>();
        List<Map<String, Object>> nameList = new ArrayList<>();
        String sql=" SELECT SUM(acq_num_of_people) flows,DATE_FORMAT(acq_time,'%H') AS hours FROM base_disanfang \n" +
                "        WHERE DATE(acq_time) = CURDATE()\n" +
                "          AND province_id = ? \n" +
                "        GROUP BY  DATE_FORMAT(acq_time,'%H')";
        Connection connection = null;
        PreparedStatement pStatement = null;
        connection = getConnection();
        try {
            pStatement = connection.prepareStatement(sql);
            pStatement.setObject(1,proId);
            ResultSet rs=pStatement.executeQuery();
            while(rs.next()){
                map = new HashMap<String,Object>();
                map.put("value",rs.getInt(1));
                map.put("name",rs.getString(2));
                nameList.add(map);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        //return JSONArray.toJSONString(mapList);
        return nameList;
    }
public List<Map<String, Object>> getFlowsHoursThreeByProvince(Integer proId){
        Map<String,Object> map = new HashMap<String,Object>();
        List<Map<String, Object>> mapList = new ArrayList<>();
        List<Map<String, Object>> nameList = new ArrayList<>();
        String sql=" SELECT SUM(acq_num_of_people) flows,DATE_FORMAT(acq_time,'%H') AS hours FROM base_three " +
                "        WHERE DATE(acq_time) = CURDATE() " +
                "          AND province_id = ? " +
                "        GROUP BY  DATE_FORMAT(acq_time,'%H')";
        Connection connection = null;
        PreparedStatement pStatement = null;
        connection = getConnection();
        try {
            pStatement = connection.prepareStatement(sql);
            pStatement.setObject(1,proId);
            ResultSet rs=pStatement.executeQuery();
            while(rs.next()){
                map = new HashMap<String,Object>();
                map.put("value",rs.getInt(1));
                map.put("name",rs.getString(2));
                nameList.add(map);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        //return JSONArray.toJSONString(mapList);
        return nameList;
    }

开始处理List<Map>结果集:

//根据省份编码获取小时段的客流信息(日客流趋势) basedisanfang的
        List<Map<String, Object>> disanfangLists = zhiXingMysql.getFlowsHoursDiSanFangByProvince(proId);
        //根据省份编码获取小时段的客流信息(日客流趋势) basethree的
        List<Map<String, Object>> threeLists = zhiXingMysql.getFlowsHoursThreeByProvince(proId);
        Map<Integer, Long> mapTotal = new HashMap<>();
        //将数据放在map集合中
        for (Map<String, Object> map : disanfangLists) {
            mapTotal.put(Integer.parseInt(map.get("name").toString()), Long.parseLong(map.get("value").toString()));
        }
        for (Map<String, Object> map : threeLists) {
            //获取basethree集合中的键
            int threekey = Integer.parseInt(map.get("name").toString());
            //获取mapTotal集合中的键,如果有,则相加,如果没有,则直接用
            Set set = mapTotal.keySet();
            for (Object hours : set) {
                //判断三方的里面有没有这个键
                if (Integer.parseInt(hours.toString()) == threekey) {
                    //有的话,加起来
                    Long flows = Long.parseLong(map.get("value").toString()) + mapTotal.get(threekey);
                    //重新添加到map集合中,替换到原来的
                    mapTotal.put(threekey, flows);
                }
            }

            //获取basethree的所有键
            Set basethreeSet = map.keySet();
            Set mapTotalSet = mapTotal.keySet();
            //遍历一下看看mapTotal里面有没有都加进去
            Iterator ite1 = mapTotalSet.iterator();
            Iterator ite2 = basethreeSet.iterator();
            while (ite2.hasNext()) {
                if (mapTotalSet.contains(ite2.next())) {
                    mapTotal.put(Integer.parseInt(map.get("name").toString()), Long.parseLong(map.get("value").toString()));
                }
            }
        }
        Set mapTotalSet = mapTotal.keySet();
        List<Integer> hourList = new ArrayList<>();;
        List<Long> flowsList = new ArrayList<>();
        //将键和值都放在VO中
        for (Object hours : mapTotalSet) {
            hourList.add(Integer.parseInt(hours.toString()));
            flowsList.add(mapTotal.get(hours));
        }

HomeVO类的字段如下:

/**
 * @author: muxiongxiong
 * @date: 2021年11月27日 下午 1:31
 * 公众号:雄雄的小课堂
 * 博客:https://blog.csdn.net/qq_34137397
 * 个人站:http://www.穆雄雄.com
 * 个人站:http://www.muxiongxiong.cn
 * @Description: 首页大屏的封装类
 */

public class HomeVO {
    //客流排行
    private  List<Map<String, Object>> flowOrderByList = new ArrayList<>();
    //场馆客流占比
    private  List<Object> flowZhanBiByDept = new ArrayList<>();
    //月客流趋势
    private  List<BussFlowList> flowQuShiByMonth = new ArrayList<>();
    //日客流趋势(暂时没有用)
    private   Map<Integer, Long> flowQuShiByDays = new HashMap<>();
     //客流前五的场馆信息
    private List<Object> flowNameOrderFive = new ArrayList<>();
    //小时客流趋势的小时
    private List<Integer> hoursList = new ArrayList<>();
    //小时客流趋势的客流
    private List<Long> flowsList = new ArrayList<>();


    public List<Map<String, Object>> getFlowOrderByList() {
        return flowOrderByList;
    }

    public void setFlowOrderByList(List<Map<String, Object>> flowOrderByList) {
        this.flowOrderByList = flowOrderByList;
    }

    public List<Object> getFlowZhanBiByDept() {
        return flowZhanBiByDept;
    }

    public void setFlowZhanBiByDept(List<Object> flowZhanBiByDept) {
        this.flowZhanBiByDept = flowZhanBiByDept;
    }

    public List<BussFlowList> getFlowQuShiByMonth() {
        return flowQuShiByMonth;
    }

    public void setFlowQuShiByMonth(List<BussFlowList> flowQuShiByMonth) {
        this.flowQuShiByMonth = flowQuShiByMonth;
    }

    public Map<Integer, Long> getFlowQuShiByDays() {
        return flowQuShiByDays;
    }

    public void setFlowQuShiByDays(Map<Integer, Long> flowQuShiByDays) {
        this.flowQuShiByDays = flowQuShiByDays;
    }

    public List<Object> getFlowNameOrderFive() {
        return flowNameOrderFive;
    }

    public void setFlowNameOrderFive(List<Object> flowNameOrderFive) {
        this.flowNameOrderFive = flowNameOrderFive;
    }

    public List<Integer> getHoursList() {
        return hoursList;
    }

    public void setHoursList(List<Integer> hoursList) {
        this.hoursList = hoursList;
    }

    public List<Long> getFlowsList() {
        return flowsList;
    }

    public void setFlowsList(List<Long> flowsList) {
        this.flowsList = flowsList;
    }
}

最后是前端封装到echarts中的代码,因为,如果现在是17点的话,则17点之后的数据应该为0才对,所以我这边的思路是先构建一个0-24小时的时间集合,直接扔到面积图的X轴,y轴则是从VO实体类中获取。

这边还会有个问题,就是查询的结果中可能有问题,比如7时没有数据,那么返回的结果就是5 6 8 9 时,没有7时,所以这个地方还需要进行一次与时间遍历判断一下,如果取的时间等于当前X轴的上的某时,才将数据放在Y轴的集合中,否则就填充0

代码如下:

 //根据省份获取每日客流趋势
    //this.hoursList = null;
    if (this.hoursList.length === 0) {
      //构造小时
      for (let i = 0; i < 24; i++) {
        this.hoursList.push(i + "时");
      }
    }
    this.hoursFlowList = new Array(24).fill(0);
    for (var j = 0; j < this.homeVo.hoursList.length; j++) {
      //获取时间,且格式化一下
      var shijian = this.homeVo.hoursList[j];
      for (let i = 0; i < this.hoursFlowList.length; i++) {
        if (shijian == i) {
          this.hoursFlowList.splice(shijian, 1this.homeVo.flowsList[j]);
        }
      }

    }
    /*这个不能放在括号外面,放外面执行的顺序不一样*/
    this.drawLines("lines"this.hoursList, this.hoursFlowList);
  })
},

data中声明的变量如下:

   hoursList:[],   //小时的集合
      hoursFlowList:[], //小时段的客流集合
      homeVo:[],  //返回的数据结果

好了,到现在为止,已经都实现了,这种方法可能不是最好的方法,大家也可以说出你们的思路~

雄雄的小课堂

2021/12/15  阅读:60  主题:自定义主题1

作者介绍

雄雄的小课堂