最近公司有业务需求:要求实现批量分配操作,详情如下:

    1. 选择多个客户
    2. 选择多个员工
    3. 给每个员工分配客户
    4. 要求分配的客户数量尽量平均
    5. 选择的员工数大于选择的客户数时,一个员工分配一个客户,不够的就不分配
    6. 选择的员工数等于客户数时,一个员工对应一个客户
    7. 分配的客户最好是随机的。
    8. 为了实现上述需求,需要设计一个随机平均分配算法
    9. 一开始我的设计思路比较简单,遍历员工集合和客户集合,依次分配单个客户给每个员工,直到分完为止,但是这种实现效率很低,也达不到随机的效果。
    10. 转变思路,先分析、设计数据存储结构,入参为两个List集合,返回数据类型为:
      一、 Map,每个员工作为key,value为分配的客户列表;
      二、List>,员工作为key,value为分配给他的客户,每个员工-客户列表都对应一个Map集合,这样所有的员工-客户列表组合成一个List>集合
      最终我采用了第二种数据结构,下面是实现代码:
      这个代码可能还存在部分问题,可以继续优化改进 ```java import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.StringUtils;

    import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set;

    /**

    • @author
    • @version 1.0
    • @description 平均分配算法
    • @date 2021-09-11 08:53 */ public class AverageDataUtil {

      /**

      • 定义存储待分配数据集合 */ private static List list = Lists.newArrayList();

        /**

      • 定义存储分组数据的结构,Map去除泛型,适配多种数据类型格式,使用时需注意 */ private static List los = Lists.newArrayList();

        /**

      • 供外部调用的平均分配方法 *
      • @param visitorIds 客户列表
      • @param sellerIds 员工列表
      • @return List */ public static List averageData(List visitorIds, List sellerIds) { initCollections(visitorIds, sellerIds); if (visitorIds.size() >= sellerIds.size()) {

        1. groupByData(los.size());
        2. return getMaps();

        } else {

        1. groupByData(list.size());
        2. return getMaps();

        } }

        /**

      • 返回数据,清空静态缓存 *
      • @return List */ @NotNull private static List getMaps() { List listMap = Lists.newArrayList(); listMap.addAll(los); //清空静态数据 los = Lists.newArrayList(); list = Lists.newArrayList(); return listMap; }

        /**

      • 分配数据 *
      • @param size 分组大小 */ private static void groupByData(int size) { List augmented = list;

        List> lists = chunk2(augmented, size);

        for (int i = 0; i < size; i++) {

        1. Map map = los.get(i);
        2. Iterator iterator = map.keySet().iterator();
        3. if (iterator.hasNext()) {
        4. String next = (String) iterator.next();
        5. map.put(next, lists.get(i));
        6. }

        } }

        /**

      • 初始化集合数据 *
      • @param visitorIds 待分配数据
      • @param sellerIds 分配目标 */ private static void initCollections(List visitorIds, List sellerIds) { //每次调用前清空数据 if (list.size() > 0) {

        1. list = Lists.newArrayList();

        } if (los.size() > 0) {

        1. los = Lists.newArrayList();

        } list.addAll(visitorIds); List>> list1 = new ArrayList<>(); for (String sellerId : sellerIds) {

        1. Map<String, List<String>> map = new HashMap<>(16);
        2. List<String> list = new ArrayList<>();
        3. map.put(sellerId, list);
        4. list1.add(map);

        } los.addAll(list1); }

        /**

      • 分组数据-核心算法,勿动 *
      • @param list 需分配数据
      • @param group 分组大小
      • @param 分组数据泛型
      • @return 分组结果 */ private static List> chunk2(List list, int group) { if (CollectionUtils.isEmpty(list)) {

        1. return Lists.newArrayList();

        } List> result = Lists.newArrayList(); Map> temp = Maps.newHashMap(); for (int i = 0; i < list.size(); i++) {

        1. if (temp.containsKey(i % group)) {
        2. Set<T> ts = temp.get(i % group);
        3. ts.add(list.get(i));
        4. temp.put(i % group, ts);
        5. } else {
        6. Set<T> ts = Sets.newHashSet();
        7. ts.add(list.get(i));
        8. temp.put(i % group, ts);
        9. }

        } for (Set ts : temp.values()) {

        1. result.add(Lists.newArrayList(ts));

        } return result; }

        public static void main(String[] args) { List visitorIds = new ArrayList<>(); visitorIds.add(“aa”); visitorIds.add(“bb”); visitorIds.add(“cc”); visitorIds.add(“dd”); visitorIds.add(“ee”); visitorIds.add(“ff”); visitorIds.add(“gg”); visitorIds.add(“hh”); visitorIds.add(“ii”); visitorIds.add(“jj”); visitorIds.add(“kk”); List sellerIds = new ArrayList<>(); sellerIds.add(“11”); sellerIds.add(“22”); sellerIds.add(“33”); sellerIds.add(“44”); sellerIds.add(“55”); sellerIds.add(“66”); sellerIds.add(“77”); sellerIds.add(“88”); sellerIds.add(“99”); sellerIds.add(“1010”); sellerIds.add(“1111”); List maps = averageData(visitorIds, sellerIds); System.out.println(maps); }

    } ```