Java模拟发红包
1.方法代码2.测试代码
平时各位朋友在开发的过程中,如果是商城或者金融项目会涉及到发红包等操作,最近就有业务用到了这个,所以就写了一个,结果比较均衡,不会出现暴雷(一个或几个红包特别大)情况。
talk is cheap,show me your code
1.方法代码
public static List
<Integer> redPacket(int pool
, int n
, List
<Integer> list
) {
if (list
== null
) {
list
= new ArrayList<>(n
);
}
if (pool
< n
) {
return average(pool
, pool
);
}
int i
= pool
/ n
;
int nextInt
= new Random().nextInt(i
) + 1;
int count
= nextInt
;
if (list
.isEmpty()) {
list
.add(nextInt
);
for (int j
= 0, k
= n
- 1; j
< k
; j
++) {
int i2
= i
- nextInt
;
nextInt
= new Random().nextInt(i
+ i2
) + 1;
list
.add(nextInt
);
count
+= nextInt
;
}
} else {
list
.set(0, list
.get(0) + nextInt
);
for (int j
= 0, k
= n
- 1; j
< k
; j
++) {
int i2
= i
- nextInt
;
nextInt
= new Random().nextInt(i
+ i2
) + 1;
list
.set(j
, list
.get(j
) + nextInt
);
count
+= nextInt
;
}
}
int remaining
= pool
- count
;
if (remaining
>= n
) {
redPacket(remaining
, n
, list
);
} else {
int lucky
= new Random().nextInt(n
);
list
.set(lucky
, list
.get(lucky
) + remaining
);
}
return list
;
}
public static List
<Integer> average(int pool
, int n
) {
if (n
<= 0 || n
> pool
) {
return new ArrayList<>();
}
if (n
== 1) {
return Collections
.singletonList(pool
);
}
List
<Integer> list
= new ArrayList<>();
int remain
= pool
% n
;
int ave
= pool
/ n
;
if (remain
== 0) {
for (int i
= 0; i
< n
; i
++) {
list
.add(ave
);
}
return list
;
}
int last
= remain
+ ave
;
while (pool
!= last
) {
pool
= pool
- ave
;
list
.add(ave
);
}
list
.add(last
);
return list
;
}
2.测试代码
若模拟微信发红包,200块/100个红包,执行一次4ms,执行10000次500ms出头
public static void main(String
[] args
) {
int pool
= 200 * 100;
int num
= 100;
long start
= System
.currentTimeMillis();
for (int i
= 0; i
< 10000; i
++) {
List
<Integer> list
= redPacket(pool
, num
, new ArrayList<>());
int count
= 0;
for (Integer integer
: list
) {
count
+= integer
;
}
if (list
.size() != num
|| count
!= pool
) System
.err
.println("data error");
System
.out
.println(list
);
}
System
.out
.println(System
.currentTimeMillis() - start
);
}