微信上有一个大家都很喜欢的功能,就是抢红包。本文就自己写一个java初始化红包的方法,希望大家给点意见。
/**
* @param money 红包的总金额,单位是分
* @param num 红包的个数
* @return 每个红包的金额,单位为分
*/
public static List<BigDecimal> test(BigDecimal money,BigDecimal num){
BigDecimal min = MIN_MONEY.multiply(num); //红包的总金额不能小于这个值,否则不够分
BigDecimal max = money.subtract(MIN_MONEY.multiply(num)).setScale(0,BigDecimal.ROUND_HALF_UP); //每个红包的金额不能大于这个值,否则不够分
//MathContext mc = new MathContext(4,RoundingMode.HALF_UP);
//MathContext moneyMc = new MathContext(2,RoundingMode.HALF_UP);
BigDecimal remainMoney = money;
List<BigDecimal> result = new LinkedList<BigDecimal>();
Random r = new Random();
//生成权重
List<BigDecimal> weightList = new ArrayList<BigDecimal>();
BigDecimal sum = new BigDecimal(0D);
for(int i = 0;i<num.intValue();i++){
BigDecimal temp = new BigDecimal(r.nextDouble());
weightList.add(temp);
sum = sum.add(temp);
}
//计算金额
for(int i=0;i<num.intValue()-1;i++){ //少计算一个,最后一个红包得到剩下的金额
BigDecimal tempMoney = money.multiply(weightList.get(i)).divide(sum, 0, BigDecimal.ROUND_HALF_UP);
if(tempMoney.compareTo(max)==1){
tempMoney = max;
}
if(tempMoney.compareTo(MIN_MONEY)==-1){
tempMoney = MIN_MONEY;
}
remainMoney = remainMoney.subtract(tempMoney);
result.add(tempMoney);
}
result.add(remainMoney.setScale(0,BigDecimal.ROUND_HALF_UP)); //最后一个
return result;
}
大体的思路就是先生成对应数量的随机数,然后计算出总和,在计算出每个数所占的比例。这里把单位换算成了分,最小为1分钱,最大金额也要进行限制,以防止剩下的钱不够分。
有时候有的人喜欢这样玩,1毛钱的红包发9个,总会有一个人抢到2分钱,类似一种抽签。直接用上面的方法,大概率最后一个包是2分钱,也就达不到抽签的目的了。这时候可以在进行抢红包的时候设置随机选取一个index,如下
int size = list.size();
for(int i=0;i<size;i++){
int rand = r.nextInt(list.size());
System.out.println("第"+(i+1)+"包的金额是"+list.get(rand).divide(new BigDecimal(100)));
list.remove(rand);
}
这时候就保证不会是最后一个红包总是2分钱了