基于BigDecimal类实现微信红包算法的功能
BigDecimal类
java.math.BingDecimal类从java.math.Number类继承而来,用于表示精度较高的数值类型的封装类型,一般用于精度要求较高的程序中,比如银行账户的金额属性。
他的常见构造器有:
- java.math.BigDecimal(String s)
- java.math.BigDecimal(double d)
- java.math.BigDecimal(long l)
- java.math.BigDecimal(int i)
他的常见方法有:
- add(BigDecimal b):与另一个BigDecimal执行相加运算
- subtract(BigDecimal b):与另一个BigDecimal执行相减运算
- multiply(BigDecimal b):与另一个BigDecimal执行相乘运算
- divide(BigDecimal b):与另一个BigDecimal执行相除运算
如何基于BingDecimal类实现微信红包算法呢:
首先定义一个红包总金额和要发的红包的个数:
BigDecimal a = new BigDecimal(total);
BigDecimal b = new BigDecimal(count);
然后,判断红包个数和总金额之间的关系:
- 总金额除以个数小于0.01–>那么抛出金额小于0.01异常
- 总金额除以红包个数等于0.01–>那么每个红包都是0.01元
if (count <= 0) {
throw new Exception("RedBagNumberCanNotLess1");
}
if (c.doubleValue() < 0.01) {
throw new Exception("EachRedBagCanNotLess0.01");
}
if (c.doubleValue() == 0.01) {
for (int i = 0; i < count; i++) {
list.add(new BigDecimal("0.01"));
}
return list;
}
- 如果总金额除以总个数大于0.01那么就在总金额中随机红包金额,每次随机完就将总金额减去随机出去的金额,如果随机到最后一个人,那么就直接将剩余的金额给到最后一个人。
BigDecimal temp = a;
BigDecimal min = new BigDecimal("0.01");
while (count > 0) {
if (count == 1) {
list.add(temp);
} else {
BigDecimal link = min.multiply(b);
b = b.subtract(new BigDecimal(1));
BigDecimal temp1 = temp.subtract(link);
BigDecimal temp2 = temp1.divide(new BigDecimal(2));
if (d()) {
temp1 = getEach(temp1);
} else {
temp1 = getEach(temp2);
}
list.add(temp1);
temp = temp.subtract(temp1);
}
count--;
}
return list;
- 将每次随机金额的方法私有起来,并且每次随机金额的时候将金额格式化为小数点后两位在传出来
private BigDecimal getEach(BigDecimal a) {
double a1 = a.doubleValue();
DecimalFormat df = new DecimalFormat("#.##");
double temp = Math.random() * a1 + 0.01;
BigDecimal t1 = new BigDecimal(df.format(temp));
return t1;
}
所有代码如下:
package com.red.bag;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Random;
import org.omg.CosNaming.Binding;
public class RedBag {
String total;
int count;
ArrayList<BigDecimal> list = new ArrayList<>();
public static void main(String[] args) throws Exception {
RedBag rd=new RedBag();
rd.getRedBag("5", 5);
rd.show();
}
public ArrayList<BigDecimal> getRedBag(String total, int count) throws Exception {
BigDecimal a = new BigDecimal(total);
BigDecimal b = new BigDecimal(count);
BigDecimal c=a.divide(b,MathContext.DECIMAL32);
if (count <= 0) {
throw new Exception("RedBagNumberCanNotLess1");
}
if (c.doubleValue() < 0.01) {
throw new Exception("EachRedBagCanNotLess0.01");
}
if (c.doubleValue() == 0.01) {
for (int i = 0; i < count; i++) {
list.add(new BigDecimal("0.01"));
}
return list;
}
BigDecimal temp = a;
BigDecimal min = new BigDecimal("0.01");
while (count > 0) {
if (count == 1) {
list.add(temp);
} else {
BigDecimal link = min.multiply(b);
b = b.subtract(new BigDecimal(1));
BigDecimal temp1 = temp.subtract(link);
BigDecimal temp2 = temp1.divide(new BigDecimal(2));
if (d()) {
temp1 = getEach(temp1);
} else {
temp1 = getEach(temp2);
}
list.add(temp1);
temp = temp.subtract(temp1);
}
count--;
}
return list;
}
public void show() {
for (BigDecimal n : list) {
System.out.println(n);
}
}
private BigDecimal getEach(BigDecimal a) {
double a1 = a.doubleValue();
DecimalFormat df = new DecimalFormat("#.##");
double temp = Math.random() * a1 + 0.01;
BigDecimal t1 = new BigDecimal(df.format(temp));
return t1;
}
public boolean d() {
Random r = new Random();
return r.nextBoolean();
}
}
如上代码是将5元红包随机分给5个人
程序运行结果如下图: