java双字段分组统计小技巧

前段时间有人抛出了这样一个问题:
这是一个java接口,接受的数据是一个集合List,范型是一个对象,对象有2个重要字段,暂且叫为type1和type2吧,现在需要根据type1和type2分组,并且,当type1为1时,每个50个需要单独一组,最后不足50,单独一个组;type1为2时,每1000个单独一组,最后不足1000一个组


咋一看这样的问题,就是一个统计问题,但是如何用高效的代码去统计,会直接影响着接口的效率问题
首先,我们先来分析一下题目:
第一步,我们要把数据分组,必然要循环这个集合List
第二步,我们要分割数据,按50和1000再分组,再次循环,分割处理

很显然,这样一分析,至少需要循环2次,才能处理出来结果,并且预估要写一堆代码
从效率的角度出发,最多只能循环一次,就要搞定,否则接口的性能就不能保证了。。。
废话不多说,直接上代码

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;

/**
 * @author yanghao
 * @version GroupTest.java, v 0.1 2019-04-01 20:24
 */
public class GroupTest {

    public static void main(String[] args){

        //待处理集合
        List<Group> groupList = buildGroup();

        //转换后存储map   key = type1_type2_num
        Map<String, List<Group>> goupMap = Maps.newHashMap();
        //记录分组编号  key = type1_type2
        Map<String, Integer> numMap = Maps.newHashMap();

        //map的key组合
        String mapkey = "";
        //按照50和1000分组编号
        int index;
        //每个type1和type2分组后的集合
        List<Group> glist = null;

        //开始循环处理数据。。。
        for(Group group : groupList){
            mapkey = group.getType1() + "_" + group.getType2();

            //==============1.查询小分组编号==============
            if(numMap.get(mapkey) == null){
                index = 1;
                numMap.put(mapkey, index);
            }else {
                index = numMap.get(mapkey);
            }

            //==============2.查询小分组集合==============
            //小分组key
            mapkey += "_" + index;

            if(goupMap.get(mapkey) == null){
                glist = Lists.newArrayList();
            }else {
                glist = goupMap.get(mapkey);
            }

            //==============3.放入goupMap==============
            glist.add(group);
            goupMap.put(mapkey, glist);

            //==============4.判断小分组是否超过分组上限==============
            if((group.getType1() == 1 && glist.size() >= 50) ||
                    (group.getType1() == 2 && glist.size() >= 1000)) {

                //分组编号加1后重新放入编号map
                index ++;
                numMap.put(group.getType1() + "_" + group.getType2(), index);
            }

        }

        System.out.println("goupMap == " + goupMap);

    }

    /**
     * 组建测试数据
     * @return
     */
    private static List<Group> buildGroup() {
        List<Group> groupList = Lists.newArrayList();

        Group group1 = new Group();
        group1.setType1(1);
        group1.setType2("a");
        groupList.add(group1);

        Group group2 = new Group();
        group2.setType1(1);
        group2.setType2("b");
        groupList.add(group2);

        Group group3 = new Group();
        group3.setType1(2);
        group3.setType2("c");
        groupList.add(group3);

        Group group4 = new Group();
        group4.setType1(2);
        group4.setType2("c");
        groupList.add(group4);

        return groupList;
    }

}

运行结果如下:

goupMap == {2_c_1=[Group(type1=2, type2=c), Group(type1=2, type2=c)], 1_b_1=[Group(type1=1, type2=b)], 1_a_1=[Group(type1=1, type2=a)]}

可以看出,基本已经按照type1和type2进行分组了

再来验证一下,上限50和1000,由于测试数据不多,将1000改为了1,进行了测试,结果如下:

goupMap == {2_c_2=[Group(type1=2, type2=c)], 2_c_1=[Group(type1=2, type2=c)], 1_b_1=[Group(type1=1, type2=b)], 1_a_1=[Group(type1=1, type2=a)]}

从结果看出,上限的效果也达到了,达到1时,分组为由2_c_1变为2_c_2了。。。


有的时候,有些办法不可行的时候,我们可以转换我们的思路,很好的利用Map实现了我们想要的,我们要学会转换我们的思想,做事会事半功倍的!

猜你喜欢

转载自blog.csdn.net/weixin_43968234/article/details/88958288