先模拟一个场景下,某个组织中,存在一个创建/所有者账号 ownerUid,以及多个成员账号 uidList,如果想要平均的获取到每一个成员的 uid,为了公平,就依次获取即可,寻找一个相对高效的方式。

    方式:利用 Redis 进行存储,配合算法处理,为了演示简单,我这里用一个公共的 Map 模拟 Redis。

    • NumberUtils 来自 org.apache.commons.lang3.math,就是第一次为空时,给一个默认值,然后将 String 转为 int。也可以直接用基本语法实现。 ```java package cn.ideal;

    import org.apache.commons.lang3.math.NumberUtils; import org.junit.Test;

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

    /**

    • @author baiwenhuang
    • @date 2022-02-24 10:35 上午 **/ public class Test1 {

      Map catchMap = new HashMap<>();

      @Test public void test() {

      1. List<Long> uidList = new ArrayList<>();
      2. uidList.add(1001L);
      3. uidList.add(1002L);
      4. uidList.add(1003L);
      5. uidList.add(1004L);
      6. uidList.add(1005L);
      7. uidList.add(1006L);
      8. for (int i = 0; i < 20; i++) {
      9. Long nextUid = averageNextUid(1000L, uidList);
      10. }

      }

      /**

      • 算法
      • @param ownerUid 兜底账号
      • @param uidList 待分配账号集合(需要分配的)
      • @return 本次分配的账号 */ private Long averageNextUid(Long ownerUid, List uidList) { if (uidList.isEmpty()) {

        1. return ownerUid;

        } int size = uidList.size(); String value = catchMap.get(cursorKey(ownerUid)); int index = NumberUtils.toInt(value, -1); index = (index + 1) % size; catchMap.put(indexKey(ownerUid), String.valueOf(index));

        System.out.println(“缓存值 % 数量 = “ + index + “ % “ + size + “ = “ + index % size + “ 取出集合中的第 “ + (index % size + 1) + “个数据: “ + uidList.get(index % size));

        return uidList.get(index % size); }

        /**

      • 此处随意,模拟拼一个 key 具体带业务名即可
      • @param ownerUid 主账号
      • @return key */ private String indexKey(Long ownerUid) { return ownerUid + “_index”; } }
        1. 运行结果:
        2. ```java
        3. 缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
        4. 缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
        5. 缓存值 % 数量 = 2 % 6 = 2 取出集合中的第 3个数据: 1003
        6. 缓存值 % 数量 = 3 % 6 = 3 取出集合中的第 4个数据: 1004
        7. 缓存值 % 数量 = 4 % 6 = 4 取出集合中的第 5个数据: 1005
        8. 缓存值 % 数量 = 5 % 6 = 5 取出集合中的第 6个数据: 1006
        9. 缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
        10. 缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
        11. 缓存值 % 数量 = 2 % 6 = 2 取出集合中的第 3个数据: 1003
        12. 缓存值 % 数量 = 3 % 6 = 3 取出集合中的第 4个数据: 1004
        13. 缓存值 % 数量 = 4 % 6 = 4 取出集合中的第 5个数据: 1005
        14. 缓存值 % 数量 = 5 % 6 = 5 取出集合中的第 6个数据: 1006
        15. 缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
        16. 缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
        17. 缓存值 % 数量 = 2 % 6 = 2 取出集合中的第 3个数据: 1003
        18. 缓存值 % 数量 = 3 % 6 = 3 取出集合中的第 4个数据: 1004
        19. 缓存值 % 数量 = 4 % 6 = 4 取出集合中的第 5个数据: 1005
        20. 缓存值 % 数量 = 5 % 6 = 5 取出集合中的第 6个数据: 1006
        21. 缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
        22. 缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
        还可以这样,其实本质都是一个意思,只是到 size 后下标归零。
        1. private Long averageNextUid2(Long ownerUid, List<Long> uidList) {
        2. if (uidList.isEmpty()) {
        3. return ownerUid;
        4. }
        5. int size = uidList.size();
        6. String indexStr = catchMap.get(cursorKey(ownerUid));
        7. int index = NumberUtils.toInt(indexStr, -1);
        8. int newIndex = index < size - 1 ? index += 1 : 0;
        9. catchMap.put(cursorKey(ownerUid), String.valueOf(newIndex));
        10. return uidList.get(newIndex);
        11. }