先模拟一个场景下,某个组织中,存在一个创建/所有者账号 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() {
List<Long> uidList = new ArrayList<>();
uidList.add(1001L);
uidList.add(1002L);
uidList.add(1003L);
uidList.add(1004L);
uidList.add(1005L);
uidList.add(1006L);
for (int i = 0; i < 20; i++) {
Long nextUid = averageNextUid(1000L, uidList);
}
}
/**
- 算法
- @param ownerUid 兜底账号
- @param uidList 待分配账号集合(需要分配的)
@return 本次分配的账号 */ private Long averageNextUid(Long ownerUid, List
uidList) { if (uidList.isEmpty()) { 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”;
}
}
还可以这样,其实本质都是一个意思,只是到 size 后下标归零。运行结果:
```java
缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
缓存值 % 数量 = 2 % 6 = 2 取出集合中的第 3个数据: 1003
缓存值 % 数量 = 3 % 6 = 3 取出集合中的第 4个数据: 1004
缓存值 % 数量 = 4 % 6 = 4 取出集合中的第 5个数据: 1005
缓存值 % 数量 = 5 % 6 = 5 取出集合中的第 6个数据: 1006
缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
缓存值 % 数量 = 2 % 6 = 2 取出集合中的第 3个数据: 1003
缓存值 % 数量 = 3 % 6 = 3 取出集合中的第 4个数据: 1004
缓存值 % 数量 = 4 % 6 = 4 取出集合中的第 5个数据: 1005
缓存值 % 数量 = 5 % 6 = 5 取出集合中的第 6个数据: 1006
缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
缓存值 % 数量 = 2 % 6 = 2 取出集合中的第 3个数据: 1003
缓存值 % 数量 = 3 % 6 = 3 取出集合中的第 4个数据: 1004
缓存值 % 数量 = 4 % 6 = 4 取出集合中的第 5个数据: 1005
缓存值 % 数量 = 5 % 6 = 5 取出集合中的第 6个数据: 1006
缓存值 % 数量 = 0 % 6 = 0 取出集合中的第 1个数据: 1001
缓存值 % 数量 = 1 % 6 = 1 取出集合中的第 2个数据: 1002
private Long averageNextUid2(Long ownerUid, List<Long> uidList) {
if (uidList.isEmpty()) {
return ownerUid;
}
int size = uidList.size();
String indexStr = catchMap.get(cursorKey(ownerUid));
int index = NumberUtils.toInt(indexStr, -1);
int newIndex = index < size - 1 ? index += 1 : 0;
catchMap.put(cursorKey(ownerUid), String.valueOf(newIndex));
return uidList.get(newIndex);
}