前言

有的时候,我们需要做一个类似微信发红包的逻辑,这就涉及到随机拆分红包的功能了。

那么如何去实现这个能力呢?

最简单的逻辑:先创建一个长度等于发放人数的数组,先赋值一个初始值,防止随机分配的时候未进行赋值。然后将剩下的值,随机分配的这个数组中即可。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* 数字随机拆分-类似发红包
* @param allNum 被拆分的数字
* @param split 拆成几个
* @return 拆分后的集合
*/
public static List<Integer> splitNum(int allNum, int split){

if(allNum < split || allNum < 1){
throw new IllegalArgumentException("被拆分的总数小于需要拆分的份数");
}
// 创建一个长度等于split的数组
Integer[] array = new Integer[split];
// 先给数组的每个元素赋值最基础的值:1
Arrays.fill(array,1);
// 减掉分配的数额
allNum -= split;

// while遍历总额,随机进行分配,逐个元素进行累计赋值
int i = 0;
Random random = new Random();
while (allNum > 0){
// 最后一个直接赋值给第一个
if(allNum == 1){
array[0] += 1;
allNum --;
}
// 随机赋值
else{
int boud = (allNum / 2) + 1;
boud = boud > 2 ? boud / 2 : boud;
int num = random.nextInt(boud) + 1;
array[i++ % split] += num;
allNum -= num;
}
}
List<Integer> res = Arrays.stream(array).collect(Collectors.toList());
// 打乱
Collections.shuffle(res);
return res;
}

测试一下:

1
2
3
4
5
6
public static void main(String[] args) {
System.out.println("10分成10份:" + splitNum(10,10));
System.out.println("100分成10份:" + splitNum(100,10));
System.out.println("10分成3份:" + splitNum(10,3));
System.out.println("500分成15份:" + splitNum(500,15));
}

输出示例:

1
2
3
4
5
10分成10份:[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
100分成10份:[3, 19, 11, 18, 6, 5, 3, 16, 10, 9]
10分成3份:[2, 5, 3]
500分成15份:[17, 15, 16, 36, 56, 15, 4, 59, 25, 22, 72, 23, 61, 48, 31]